PKU POJ 2186 Popular Cows 强连通分量

新注册了博客,正好刚刚开始做强连通专题,就当存个模板了

题目简述:n头奶牛,给出若干个欢迎关系a b,表示a欢迎b,欢迎关系是单向的,但是是可以传递的。另外每个奶牛都是欢迎他自己的。求出被所有的奶牛欢迎的奶牛的数目。

思路:先得出每个强连通分块的规模,再检查输入的每一条边,如果这边连着2个不同的强连通分块,那么被指向的分块才可能是答案。当答案不唯一时则说明至少有两头牛没有任何关系,这时输出0.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int Max = 20009;
 8 #define max(a,b) a>b?a:b
 9 
10 struct node{
11     int v,next;
12 }Edge[100000];
13 
14 int k,Dindex,Stop,Bcnt;
15 int head[Max],DFN[Max],LOW[Max],instack[Max],Stap[Max],Belong[Max];
16 int a[50009],b[50009],cnt[Max];
17 bool ok[Max];
18 
19 void add(int u,int v){
20     Edge[k].v = v;
21     Edge[k].next = head[u];
22     head[u] = k++;
23 }
24 
25 void tarjan(int i)
26 {
27     int j;
28     DFN[i]=LOW[i]=++Dindex;
29     instack[i]=true;
30     Stap[++Stop]=i;
31     for (int w=head[i];w!=-1;w=Edge[w].next)
32     {
33         j=Edge[w].v;
34         if (!DFN[j])
35         {
36             tarjan(j);
37             if (LOW[j]<LOW[i])
38                 LOW[i]=LOW[j];
39         }
40         else if (instack[j] && DFN[j]<LOW[i])
41             LOW[i]=DFN[j];
42     }
43     if (DFN[i]==LOW[i])
44     {
45         Bcnt++;
46         do
47         {
48             j=Stap[Stop--];
49             instack[j]=false;
50             Belong[j]=Bcnt;
51         }
52         while (j!=i);
53     }
54 }
55 
56 int main() {
57     int n,m;
58     while(scanf("%d%d",&n,&m) == 2){
59         memset(head,-1,sizeof(head));
60     memset(DFN,0,sizeof(DFN));
61     memset(instack,0,sizeof(instack));
62     memset(LOW,0,sizeof(LOW));
63         k = 0;
64         for(int i=0;i<m;i++){
65             scanf("%d%d",&a[i],&b[i]);
66             add(a[i],b[i]);
67         }
68         Stop=Bcnt=Dindex=0;
69         for(int i=1;i<=n;i++){
70             if(DFN[i] == 0)
71                 tarjan(i);
72         }
73         for(int i=1;i<=n;i++)
74             cnt[Belong[i]]++;
75 
76         int num = 0,ans;
77         for(int i=0;i<m;i++){
78             if(Belong[a[i]] != Belong[b[i]]){
79                 ok[Belong[a[i]]] = true;
80             }
81         }
82         for(int i=1;i<=Bcnt;i++){
83             if(!ok[i]){
84                 num++;
85                 ans = cnt[i];
86             }
87         }
88         if(num != 1)
89             printf("0\n");
90         else
91             printf("%d\n",ans);
92     }
93     return 0;
94 }
View Code
原文地址:https://www.cnblogs.com/gray035/p/2962262.html