求助!求助!求求大佬帮忙看一下tarjan
查看原帖
求助!求助!求求大佬帮忙看一下tarjan
631052
ysw0521nb楼主2022/12/20 18:05
#include<bits/stdc++.h>
using namespace std;
const int N=10050,M=100050;
int n,m;
int a[N];
struct Edge{
	int to,nxt;
}e[M],e1[M];
int h[N],cnt=1,h1[N],cnt1=1;
void add(int u,int v)
{
	e[cnt]={v,h[u]};
	h[u]=cnt++;
}
void add1(int u,int v)
{
	e1[cnt1]={v,h1[u]};
	h1[u]=cnt1++;
}
int dfn[N],val[N];
int id[N],p1[N];
bool vis[N];
int cc=0,scc=0;
stack<int> stc;
void dfss(int p)
{
	vis[p]=1;
	cc++;
	dfn[p]=val[p]=cc;
	stc.push(p);
	for(int i=h[p];i;i=e[i].nxt)
	{
		int j=e[i].to;
		if(!dfn[j])
		{
			dfss(j);
			val[p]=min(val[j],val[p]);
		}
		else if(vis[j])
			val[p]=min(val[p],dfn[j]);
	}
	
	if(dfn[p]==val[p])
	{
		int y;
		++scc;
		do{
			y = stc.top();
			stc.pop();
			vis[y] = 0;
			id[y] = scc;	//标记y点缩点后位于哪个强连通分量 
			p1[scc] += a[y];	//将y点的权加入到对应的强连通分量中 
		} while(y != p);
	}
}
int dis[N];
int spfa(int x)
{
	memset(dis,-0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
	queue<int>q;
	vis[x]=1;
	dis[x]=0;
	q.push(x);
	int sum=0;
	while(q.size())
	{
		int t=q.front();
		q.pop();
		vis[t]=0;
		sum=max(sum,dis[t]+p1[t]);
		for(int i=h1[t];i;i=e1[i].nxt)
		{
			int j=e1[i].to;
			if(dis[j]<dis[t]+p1[t])
			{
				dis[j]=dis[t]+p1[t];
				if(!vis[j])
					q.push(j);
				vis[j]=1;
			}
		}
	}
	return sum;
}
void sd()
{
	for(int i=1;i<=n;i++)
		for(int j=h[i];j;j=e[i].nxt)
		{
			int y=e[j].to;
			if(id[i]!=id[y])
				add1(id[i],id[y]);
		}
	int ans=0;
	for(int i=1;i<=scc;i++)
		ans=max(ans,spfa(i));
	cout<<ans;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int u,v;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	dfss(1);
	sd();
	return 0;
}
2022/12/20 18:05
加载中...