求调(tarjan+拓扑)
查看原帖
求调(tarjan+拓扑)
1378344
sub_10楼主2024/11/20 19:43
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,m,cnt,ind[N],low[N],dfn[N],a[N],bel[N];
int val[N],fa[N],p,scc;
int dis[N];
bool ins[N];
vector<int> e[N],g[N];
stack<int> s;
void init(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1,x,y;i<=m;i++){
		cin>>x>>y;
		e[x].push_back(y);
	}
}
void tarjan(int u){
	s.push(u);
	ins[u]=1;
	low[u]=dfn[u]=++cnt;
	for(auto v: e[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]){
		scc++;
		do{
			int t=s.top();
			s.pop();
			bel[t]=scc;
			ins[t]=0;
			val[scc]+=a[t];
		}while(s.top()!=u);
	}
}
void reinit(){
	for(int i=1;i<=n;i++){
		for(auto v:e[i]){
			if(bel[v]==bel[i]) continue;
			g[bel[i]].push_back(bel[v]);
			ind[bel[v]]++;
		}
	}
}
void topo(){
	queue<int> q;
	for(int i=1;i<=scc;i++)
		if(bel[i]==i&&ind[i]==0){
			q.push(i);
			dis[i]=val[i];
		}
	while(!q.empty()){
		int j=q.front();
		q.pop();
		for(auto v: g[j]){
			dis[v]=max(dis[v],dis[j]+val[v]);
			ind[v]--;
			if(!ind[v])
				q.push(v);
		}
	}
}
int main(){
	init();
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			tarjan(i);
	reinit();
	topo();
	int ans(INT_MIN);
	for(int i=1;i<=scc;i++)
		ans=max(ans,dis[i]);
	cout<<ans;
	return 0;
}
2024/11/20 19:43
加载中...