[poj2186]Popular Cows(targin缩点)

题意:求其他所有牛都认为其牛的牛的个数。

解题关键:targin算法模板题,缩点形成一棵树,并不一定是棵树,可能含有多个入度为0的点,寻找出度为0的点(缩点之后的点)的个数,如果个数大于0,则无解,否则输出该强连通分量内的个数。

注意targin算法的数组不需要memset。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 using namespace std;
 8 typedef long long ll;
 9 #define MAXN 10010
10 #define MAXM 100010
11 struct edge{
12     int to,nxt;
13 }e[MAXM];
14 int degree[MAXN];
15 int head[MAXN],st[MAXN],dfn[MAXN],lowest[MAXN],belong[MAXN];
16 bool inst[MAXN];
17 int n,m,scnt,top,tot;//scnt从1开始
18 void init(){
19     memset(head,-1,sizeof head);
20     memset(degree,0,sizeof degree);
21     scnt=top=tot=0;
22 }
23 
24 void add_edge(int u, int v){
25     e[tot].to=v;
26     e[tot].nxt=head[u];
27     head[u]=tot++;
28 }
29 
30 void Tarjan(int u){
31     dfn[u]=lowest[u]=++tot;
32     inst[u]=1;
33     st[top++]=u;
34     for(int i=head[u];i!=-1;i=e[i].nxt){
35         int v=e[i].to;
36         if(!dfn[v]){
37             Tarjan(v);
38             lowest[u]=min(lowest[u],lowest[v]);
39         }
40         else if(inst[v]){
41             lowest[u]=min(lowest[u],dfn[v]);//也可用lowest
42         }
43     }
44     if(dfn[u]==lowest[u]){
45         scnt++;
46         int t;
47         do{
48             t=st[--top];
49             inst[t]=false;
50             belong[t]=scnt;
51         }while(t!=u);
52     }
53 }
54 
55 inline int read(){
56     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
57     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
58     if(k=='-')x=0-x;return x;
59 }
60 
61 
62 void solve(){//缩点
63     for(int i=1;i<=n;i++)  if(!dfn[i])  Tarjan(i);
64     for(int i=1;i<=n;i++){
65         for(int j=head[i];j!=-1;j=e[j].nxt){
66             if(belong[i]!=belong[e[j].to]){
67                 degree[belong[i]]++;
68             }
69         }
70     }
71     int sum=0,x=0;
72     for(int i=1;i<=scnt;i++) if(!degree[i]) sum++,x=i;//记录索引
73     if(sum!=1){
74         printf("0\n");
75         return;
76     }
77     sum=0;
78     for(int i=1;i<=n;i++){
79         if(belong[i]==x) sum++;
80     }
81     printf("%d\n",sum);
82     return;
83 }
84 
85 int main(){
86     int a,b;
87     while(scanf("%d%d",&n,&m)!=EOF){
88         init();
89         while(m--){
90             a=read(),b=read();
91             add_edge(a,b);
92         }
93         solve();
94     }
95     return 0;
96 }

 

posted @ 2017-09-14 16:01  Elpsywk  阅读(234)  评论(0编辑  收藏  举报