40pts,求调(tarjan+spfa)
查看原帖
40pts,求调(tarjan+spfa)
636409
Headofstate1945楼主2023/11/4 11:06
#include<bits/stdc++.h>
using namespace std;
const signed N=1e4+5,M=1e5+5;
signed a[N],dfn[N],low[N],s[N],sz[N],scc[N],in[N],dis[N];
signed n,m,idx,top,cnt;
bool ins[N],vis[N];
vector<signed> g[N],G[N],ans[N];
void tarjan(signed u){
	dfn[u]=low[u]=++idx;
	s[++top]=u;ins[u]=1;
	for(auto v:g[u]){
		if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
		else if(ins[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		++cnt;
		while(1){
			signed v=s[top--];ins[v]=0;
			sz[cnt]+=a[v];
			scc[v]=cnt;
			ans[cnt].push_back(v);
			if(v==u)break;		
		}
	}
}
void spfa(){
	queue<signed> q;
	for(signed i=1;i<=cnt;i++){
		if(!in[i]){
			q.push(i);
			dis[i]=sz[i];
			vis[i]=1;
		}
	}
	while(q.size()){
		signed u=q.front();
		q.pop();
		vis[u]=1;
		for(auto v:G[u]){
			if(dis[v]<dis[u]+sz[v]){
				dis[v]=dis[u]+sz[v];
				if(!vis[v])vis[v]=1,q.push(v);
			}
		}
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(signed i=1;i<=n;i++){
		cin>>a[i];
	}
	for(signed i=1;i<=m;i++){
		signed u,v;
		cin>>u>>v;
		g[u].push_back(v);
	}
	for(signed i=1;i<=n;i++){
		if(!dfn[i])tarjan(i);
	}
	for(signed i=1;i<=n;i++){
		for(auto v:g[i]){
			if(scc[v]!=scc[i]){
				G[scc[i]].push_back(scc[v]),in[scc[v]]++;
			}
		}
	}
	spfa();
	signed ans=2e9;
	for(signed i=1;i<=cnt;i++){
		ans=min(ans,dis[i]);
	}
	cout<<ans;
	return 0;
}
2023/11/4 11:06
加载中...