强连通分量:

首先tarjan缩点重构图

之后,若出度为0的点仅有一个,那么答案即为该点代表的强连通分量中点的个数

否则,答案为0

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 const int N=10010,M=50010;
 5 const int novis=-1,over=1,nowvis=0;
 6 int size,head[M],next[M],to[M];
 7 int head2[M],next2[M],to2[M];
 8 int low[N],dfn[N],flag[N],color[N],que[N],sum[N],
 9     top,cnt,n,m,sig;
10 void tarjan(),uni(int,int),dfs(int),rebuild();
11 int find(),min(int,int);
12 int main(){
13     int ans,x,y;
14     size=0;
15     memset(head,0,sizeof(head));
16     memset(head2,0,sizeof(head2));
17     scanf("%d %d",&n,&m);
18     for (int i=1;i<=m;i++){
19         scanf("%d %d",&x,&y);
20         uni(x,y);
21     }
22     tarjan();
23     rebuild();
24     ans=find();
25     printf("%d",ans);
26     return 0;
27 }
28 void uni(int x,int y){
29     size++;
30     next[size]=head[x];
31     head[x]=size;
32     to[size]=y;
33 }
34 void tarjan(){
35     memset(flag,novis,sizeof(flag));
36     memset(color,0,sizeof(color));
37     memset(sum,0,sizeof(sum));
38     sig=cnt=top=0;
39     for (int i=1;i<=n;i++)
40         if (flag[i]==novis) dfs(i);
41 }
42 void dfs(int x){
43     que[++top]=x;
44     flag[x]=nowvis;
45     low[x]=dfn[x]=++sig;
46     for (int e=head[x];e;e=next[e]){
47         int v=to[e];
48         if (flag[v]==novis){
49             dfs(v);
50             low[x]=min(low[x],low[v]);
51         }
52         else if (flag[v]==nowvis)
53             low[x]=min(low[x],dfn[v]);
54     }
55     if (low[x]==dfn[x]){
56         int t;cnt++;
57         do{
58             t=que[top--];
59             color[t]=cnt;
60             flag[t]=over;
61             sum[cnt]++;
62         }while (t!=x);
63     }
64 }
65 void rebuild(){
66     size=0;
67     for (int u=1;u<=n;u++){
68         for (int e=head[u];e;e=next[e]){
69             int v=to[e];
70             if (color[u]!=color[v]){
71                 size++;
72                 next2[size]=head2[color[u]];
73                 head2[color[u]]=size;
74                 to2[size]=color[v];
75             }
76         }
77     }
78 }
79 int find(){
80     int ans=0;
81     for (int i=1;i<=cnt;i++)
82         if (!head2[i]){
83             if (ans) return 0;
84             else ans=sum[i];
85         }
86     return ans;
87 }
88 int min(int x,int y){
89     return x<y?x:y;
90 }
STD

 

posted on 2016-09-15 11:54  Absolutezero  阅读(302)  评论(0编辑  收藏  举报