邻接表建图,强连通分量缩为有向无环图(DAG)中的一点,若DAG中出度为0的个数有1个以上,则解不存在,若出度为0的点有1个,则解为该点强连通分量中包含的点的个数
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
#include<stack>
using namespace std;
const int maxm=100010;
const int maxn=10010;
int ind,cnt,st[maxn],dfn[maxn],low[maxn],size,n,outdegree[maxn],time[maxn],v[maxm],first[maxn],next[maxm],num[maxn];
bool instack[maxn];
int solve(){
memset(outdegree,0,sizeof(outdegree));
for(int i=1;i<=n;i++)
for(int j=first[i];j!=-1;j=next[j])
if(time[v[j]]!=time[i])
outdegree[time[i]]++;
int out=0,ans;
for(int i=1;i<=cnt;i++)
if(!outdegree[i]) { out++; ans=num[i]; }
if(out!=1) return 0;
return ans;
}
void tarjan(int x){
dfn[x]=low[x]=++ind;
st[++size]=x;
instack[x]=true;
for(int i=first[x];i!=-1;i=next[i])
if(!dfn[v[i]]){
tarjan(v[i]);
if(low[x]>low[v[i]]) low[x]=low[v[i]];
}
else if(instack[v[i]]&&dfn[v[i]]<low[x]) low[x]=dfn[v[i]];
if(low[x]==dfn[x]){
cnt++;
for(int i=st[size--];i!=x;i=st[size--]){ time[i]=cnt; num[cnt]++; instack[i]=false; }
time[x]=cnt;instack[x]=false;num[cnt]++;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in", "r", stdin);
#endif
int m;
while(cin>>n>>m){
memset(first,-1,sizeof(first));
int u;
for(int i=0;i<m;i++){
cin>>u>>v[i];
next[i]=first[u];
first[u]=i;
}
memset(instack,false,sizeof(instack));
memset(dfn,0,sizeof(dfn));
ind=size=cnt=0;
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
cout<<solve()<<endl;
}
return 0;
}