强连通分量求助
查看原帖
强连通分量求助
282080
RefreshinglyNaive楼主2020/7/24 14:30

Kosaraju算法+链式前向星+记忆化搜索

64分 求助!

#include <bits/stdc++.h>
#define maxn 50005
using namespace std;
int n,m,head1[maxn],head2[maxn],tot1,tot2,t,dp[maxn];
int vis[maxn],head3[maxn],tot3,q[maxn],f[maxn],w[maxn],sum;
struct Edge
{
	int from,to,nex;
}e1[maxn],e2[maxn],e3[maxn];
void add1(int x,int y)
{
	e1[++tot1].to=y;
	e1[tot1].from=x;
	e1[tot1].nex=head1[x];
	head1[x]=tot1;
}
void add2(int x,int y)
{
	e2[++tot2].to=y;
	e2[tot2].from=x;
	e2[tot2].nex=head2[x];
	head2[x]=tot2;
}
void add3(int x,int y)
{
	e3[++tot3].to=y;
	e3[tot3].from=x;
	e3[tot3].nex=head3[x];
	head3[x]=tot3;
}
void dfs1(int x)
{
	vis[x]=1;
	for(int i=head1[x];i;i=e1[i].nex)
	{
		int to=e1[i].to;
		if(!vis[to]) dfs1(to);
	}q[++t]=x;
}
void dfs2(int x,int y)
{
	vis[x]=0; f[x]=y; w[y]++;
	for(int i=head2[x];i;i=e2[i].nex)
	{
		int to=e2[i].to;
		if(vis[to]) dfs2(to,y);
	}
}
int dfs(int x)
{
	if(dp[x]) return dp[x];
	dp[x]=w[x];
	for(int i=head3[x];i;i=e3[i].nex)
	{
		int to=e3[i].to;
		dp[x]+=dfs(to);
	}
	return dp[x];
}
int main()
{
	ios::sync_with_stdio(false);
	int x,y;
	while(cin>>n>>m)
	{
		memset(head1,0,sizeof(head1)); tot1=0;
		memset(head2,0,sizeof(head2)); tot2=0;
		memset(head3,0,sizeof(head3)); tot3=0;
		memset(w,0,sizeof(w)); 
		memset(vis,0,sizeof(vis)); t=0;
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=m;i++)
			cin>>x>>y,add1(x,y),add2(y,x);
		for(int i=1;i<=n;i++)
			if(!vis[i]) dfs1(i);
		for(int i=n;i>=1;i--)
			if(vis[q[i]]) dfs2(q[i],q[i]);
		for(int i=1;i<=m;i++)
		{
			x=f[e1[i].from],y=f[e1[i].to];
			if(x!=y) add3(y,x);
		}
		for(int i=1;i<=n;i++)
			dfs(f[i]);
		sum=0;
		for(int i=1;i<=n;i++)
			if(f[i]==i&&dp[i]==n) sum+=w[i];
		cout<<sum<<endl;
	}
	return 0;
}

2020/7/24 14:30
加载中...