链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1051
题解
缩点之后的DAG上,如果某个SCC是唯一出度为0的SCC,这个SCC的大小就是答案。否则答案为0。
代码
//强连通分量
#include <cstdio>
#include <algorithm>
#define maxn 600000
using namespace std;
int vis[maxn], to[maxn], nex[maxn], head[maxn], tot, tid[maxn], dfn[maxn], low[maxn],
s[maxn], tim, cd[maxn], u[maxn], v[maxn], sz[maxn], N, M;
void adde(int a, int b){to[++tot]=b;nex[tot]=head[a];head[a]=tot;}
void tarjan(int pos)
{
int p;
vis[pos]=1;
s[++(*s)]=pos;
dfn[pos]=low[pos]=++tim;
for(p=head[pos];p;p=nex[p])
{
if(!vis[to[p]])tarjan(to[p]);
if(vis[to[p]]==1)low[pos]=min(low[pos],low[to[p]]);
}
if(dfn[pos]==low[pos])
for((*tid)++;s[*s+1]!=pos;(*s)--)tid[s[*s]]=*tid,vis[s[*s]]=2;
}
void init()
{
int i;
scanf("%d%d",&N,&M);
for(i=1;i<=M;i++)
{
scanf("%d%d",u+i,v+i);
adde(u[i],v[i]);
}
*tid=N;
for(i=1;i<=N;i++)if(!vis[i])tarjan(i);
for(i=1;i<=tot;i++)if(tid[v[i]]^tid[u[i]])cd[tid[u[i]]]++;
}
int dfs(int pos)
{
int p, cnt=1;
vis[pos]=1;
for(p=head[pos];p;p=nex[p])if(!vis[to[p]])cnt+=dfs(to[p]);
return cnt;
}
void work()
{
int ans=-1, i, pos;
for(i=N+1;i<=*tid;i++)
if(cd[i]==0)
if(ans==-1)ans=i;else{putchar(48);return;}
for(i=1;i<=N;i++)if(tid[i]==ans){pos=i;break;}
for(i=1,ans=0;i<=N;i++)if(tid[i]==tid[pos])ans++;
printf("%d",ans);
}
int main()
{
init();
work();
return 0;
}