开始填连通分量大坑。。

tarjan强连通分量求缩点重构图(终于知道tarjan缩点是什么意思了QWQ),出度为0的点若只有一个则输出其代表强连通分量的大小,否则无解。

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(int i=l;i<=r;i++)
 3 #define dec(i,l,r) for(int i=l;i>=r;i--)
 4 #define link(x) for(edge *j=h[x];j;j=j->next)
 5 #define mem(a) memset(a,0,sizeof(a))
 6 #define inf 1e9
 7 #define ll long long
 8 #define succ(x) (1<<x)
 9 #define NM 50000+5
10 using namespace std;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
15     return x*f;
16 }
17 struct edge{
18     int t,v;
19     edge *next;
20 }e[NM],*h[NM],*o=e;
21 void add(int x,int y){
22     o->t=y;o->next=h[x];h[x]=o;o++;
23 }
24 int n,m,ans,low[NM],d[NM],suc[NM],tot,cnt,_x,_y,out[NM];
25 stack<int >s;
26 void dfs(int x){
27     d[x]=low[x]=++tot;s.push(x);
28     link(x)
29     if(!d[j->t]){
30         dfs(j->t);
31         low[x]=min(low[x],low[j->t]);
32     }else if(!suc[j->t])
33     low[x]=min(low[x],low[j->t]);
34     if(low[x]==d[x]){
35         int t;cnt++;
36         do{
37             t=s.top();s.pop();
38             suc[t]=cnt;
39         }while(x!=t);
40     }
41 }
42 int main(){
43 //    freopen("data.in","r",stdin);
44     n=read();m=read();
45     inc(i,1,m){
46         _x=read();_y=read();
47         add(_x,_y);
48     }
49     inc(i,1,n)
50     if(!d[i])dfs(i);
51     inc(i,1,n)
52     link(i)
53     if(suc[j->t]!=suc[i])out[suc[i]]++;
54     inc(i,1,cnt)
55     if(!out[i]){
56         if(ans){
57             printf("-1\n");
58             return 0;
59         }else ans=i;
60     }
61     cnt=0;
62     inc(i,1,n)
63     if(suc[i]==ans)cnt++;
64     printf("%d\n",cnt);
65     return 0;
66 }
View Code

 

posted on 2016-01-04 19:28  onlyRP  阅读(180)  评论(0编辑  收藏  举报