bzoj1051Tarjan裸题

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
");return 0;}
37             else ans=gui[i];
38     printf("%d
",ans);
39     return 0;
40 }

tarjan差点写错,心碎

原文地址:https://www.cnblogs.com/wanglichao/p/5856125.html