tarjan缩点40pts求助,貌似拓扑写挂了?
查看原帖
tarjan缩点40pts求助,貌似拓扑写挂了?
385817
QianK楼主2021/10/20 10:34

RT

#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 100086;
int dianquan[maxn],dfn[maxn],vis[maxn],low[maxn],stac[maxn],col[maxn],in[maxn],dp[maxn];
int top,tim,sum,ans;
int n,m,u[maxn],v[maxn];
vector <int> val[maxn];
vector <int> map[maxn];
void paint(int x)
{
	top--;
	col[x]=sum;
	vis[x]=0;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++tim;
	stac[++top]=x;
	vis[x]=1;
	for(int i=0;i<val[x].size();i++)
	{
		int y=val[x][i];
		if(!dfn[y])
		{
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(vis[y])
		{
			low[x]=min(low[x],dfn[y]);
		}
	}
	if(low[x]==dfn[x])
	{
		sum++;
		while(stac[top]!=x)
		{
			int y=stac[top];
			paint(y);
			dianquan[x]+=dianquan[y];
		}
		paint(x);
	}
}
void tuopu()
{
	queue <int> q;
	for(int i=1;i<=n;i++) if(!in[i]&&low[i]==dfn[i]) q.push(i),dp[i]=dianquan[i];
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		for(int i=0;i<map[x].size();i++)
		{
			int y = map[x][i];
			dp[y]=max(dp[y],dp[x]+dianquan[y]);
		}
	}
}
void output()
{
	for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
	printf("%d",ans);
}
void check()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<map[i].size();j++) printf("%d->%d\n",i,map[i][j]);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&dianquan[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u[i],&v[i]);
		val[u[i]].push_back(v[i]); 
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i]) tarjan(i);
	}
	for(int i=1;i<=m;i++)
	{
		if(col[u[i]]!=col[v[i]]) map[u[i]].push_back(v[i]); 
	}
//	for(int i=1;i<=n;i++) if(low[i]==dfn[i]&&!in[i]) dp[i]=dianquan[i];
//	check();
	tuopu();
	output();
	return 0;
}
2021/10/20 10:34
加载中...