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;
}