1 #include<cstdio> 2 #include<iostream> 3 #define M 50008 4 using namespace std; 5 int du[M],ti,ti1,cnt,head[M],head1[M],next1[10*M],u1[10*M],next[10*M],u[M],n,m,dfn[M],low[M],t,zhan[M],f[M],bel[M],sum[M]; 6 void jia(int a1,int a2) 7 { 8 cnt++; 9 next[cnt]=head[a1]; 10 head[a1]=cnt; 11 u[cnt]=a2; 12 } 13 void jia1(int a1,int a2) 14 { 15 cnt++; 16 next1[cnt]=head1[a1]; 17 head1[a1]=cnt; 18 u1[cnt]=a2; 19 du[a1]++; 20 } 21 void tarjin(int a1) 22 { 23 dfn[a1]=low[a1]=++ti; 24 f[a1]=1; 25 t++; 26 zhan[t]=a1; 27 for(int i=head[a1];i;i=next[i]) 28 if(!dfn[u[i]]) 29 { 30 tarjin(u[i]); 31 low[a1]=min(low[a1],low[u[i]]); 32 } 33 else if(f[u[i]]) 34 low[a1]=min(low[a1],dfn[u[i]]); 35 if(dfn[a1]==low[a1]) 36 { 37 ++ti1; 38 int now=0; 39 for(;now!=a1;) 40 { 41 now=zhan[t]; 42 bel[now]=ti1; 43 sum[ti1]++; 44 f[now]=0; 45 t--; 46 } 47 } 48 } 49 void jian() 50 { 51 cnt=0; 52 for(int i=1;i<=n;i++) 53 for(int j=head[i];j;j=next[j]) 54 if(bel[i]!=bel[u[j]]) 55 jia1(bel[i],bel[u[j]]); 56 } 57 int main() 58 { 59 scanf("%d%d",&n,&m); 60 for(int i=1;i<=m;i++) 61 { 62 int a1,a2; 63 scanf("%d%d",&a1,&a2); 64 jia(a1,a2); 65 } 66 for(int i=1;i<=n;i++) 67 if(!dfn[i]) 68 tarjin(i); 69 jian(); 70 int s=0,s1; 71 for(int i=1;i<=ti1;i++) 72 if(!du[i]) 73 { 74 s++; 75 s1=i; 76 } 77 if(s>1) 78 printf("0"); 79 else 80 printf("%d",sum[s1]); 81 return 0; 82 }
按题目建图后,用tarjan缩点,统计没有出度的联通块的个数,如果只有一个,输出这个联通块内点的个数,否则为零。