tarjan缩点+判断出度为0的点
所以不需要新建边
1 #include <cstdio> 2 int n,m,p,q,N=0,time=0,T=0,sum=0,ans=0; 3 int from[50001],to[50001],nex[50001],fir[10001],dfn[10001],low[10001],l[10001],tar[10001],gui[10001],c[10001]; 4 bool que[10001]; 5 void add(int p,int q){ from[++N]=p,to[N]=q,nex[N]=fir[p],fir[p]=N;} 6 int min(int p,int q){ return (p<q)?p:q;} 7 void dfs(int k) 8 { 9 dfn[k]=low[k]=++time,l[++T]=k,que[k]=1; 10 for(int o=fir[k];o;o=nex[o]) 11 if(!dfn[to[o]]) 12 dfs(to[o]),low[k]=min(low[k],low[to[o]]); 13 else 14 if(que[to[o]]) 15 low[k]=min(low[k],dfn[to[o]]); 16 if(dfn[k]==low[k]) 17 { 18 sum++; 19 while(l[T]!=k) 20 que[l[T]]=0,tar[l[T--]]=sum,gui[sum]++; 21 que[k]=0;tar[k]=sum;T--;gui[sum]++; 22 } 23 } 24 int main() 25 { 26 scanf("%d%d",&n,&m); 27 for(int i=1;i<=m;i++) 28 scanf("%d%d",&p,&q),add(p,q); 29 for(int i=1;i<=n;i++) 30 if(!dfn[i]) dfs(i); 31 for(int i=1;i<=N;i++) 32 if(tar[from[i]]!=tar[to[i]]) 33 c[tar[from[i]]]=1; 34 for(int i=1;i<=sum;i++) 35 if(!c[i]) 36 if(ans){ printf("0\n");return 0;} 37 else ans=gui[i]; 38 printf("%d\n",ans); 39 return 0; 40 }
tarjan差点写错,心碎