求助缩点,60pts,AC6WA4
查看原帖
求助缩点,60pts,AC6WA4
342076
Union_of_Britainschanghang楼主2021/5/2 16:07

不是Tarjan或Kosaraju,是这位dalao的

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int vis[maxn],fa[maxn],dq[maxn],ru[maxn],sdq[maxn],dp[maxn];//fa:并查集的dq:点权sdq:缩点后的点权
vector<int> e[maxn],re[maxn];//e:原图re:缩点后的图
int n,m,x,y;
int cha(int x)//并查集
{
	 if(x==fa[x])return x;
    return fa[x]=cha(fa[x]);
}
void cat(int u)//缩点过程
{
	for(int i=0;i<e[u].size();i++)
	{
		int v=e[u][i];
		if(!vis[v])
		{
			vis[v]=vis[u]+1;
			cat(v);
		}
		int fu=cha(u),fv=cha(v);
		if(vis[fv]>0)
		{
			if(vis[fu]<vis[fv])fa[fv]=fu;
			else fa[fu]=fv;
		}
	}
	vis[u]=-1;
}
int main()
{
	memset(vis,0,sizeof(vis));
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>dq[i];
	for(int i=1;i<=n;i++)fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			vis[i]=1;
			cat(i);
		}
	}
	memset(ru,0,sizeof(ru));
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<e[i].size();j++)
		{
			int u=i,v=e[u][j];
			if(cha(u)!=cha(v))
			{
				ru[v]++;
				re[u].push_back(v);
				re[v].push_back(u);
			}
		}
	}
	memset(sdq,0,sizeof(sdq));
	for(int i=1;i<=n;i++)
	{
		sdq[cha(i)]+=dq[i];
	}
	queue<int> q;
	for(int i=1;i<=n;i++)
	{
		if(i==fa(i)&&!ru[i])
		{
			dp[i]=sdq[i];
			q.push(i);
		}
	}
	int ans=-0x3f3f3f3f;
	while(!q.empty())
	{
        int u=q.front();
		q.pop();
        for(int i=0;i<re[u].size();i++)
        {
            int v=re[u][i];
            dp[v]=max(dp[v],dp[u]+dp[v]);
            if(--ru[v]==0)q.push(v);
        }
        ans=max(ans,dp[u]);
    }
    cout<<ans;
	return 0;
}
2021/5/2 16:07
加载中...