POJ 2186 Popular Cows

题目传送门

题目中文翻译:

Description

每头牛的梦想就是成为牛群中最受欢迎的牛。 在一群N1 <= N <= 10,000)母牛中,你可以得到M1 <= M <= 50,000)有序的形式对(AB),告诉你母牛A认为母牛 B很受欢迎。 由于流行是传递性的,如果A认为B很受欢迎,B认为C受欢迎,那么A也会认为C受欢迎的,即使这不是输入中有序对明确规定的。 你的任务是计算被其他所有奶牛欢迎的奶牛总数量。

Input

*1行:两个空格分隔的整数,NM.

*2..1 + M行:两个空格分隔的数字AB,表示A认为B很受欢迎。

Output

*1行:单个整数,即被其他所有奶牛欢迎的奶牛总数量。

Sample Input

3 3

1 2

2 1

2 3

Sample Output

1

Hint

Cow 3 is the only cow of high popularity. 

解题思路:

首先tarjan求强连通分量,缩点找没有出度的点,如果只有一个,则答案为这个点代表的强连通分量里面所有点,如果大于一个,则答案为0.

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<stack>
 5 
 6 using namespace std;
 7 
 8 int n,m,tot,head[10001],dfn[10001],num[10001],sum,low[10001],csp,belong[10001],outd[10001];
 9 bool _in[10001];
10 struct kkk {
11     int to,next,from;
12     bool pp;
13 }e[50003];
14 stack<int> a;
15 
16 inline void add(int x,int y) {
17     e[++tot].to = y;
18     e[tot].next = head[x];
19     e[tot].from = x;
20     head[x] = tot;
21 }
22 
23 inline void tarjan(int x) {
24     int v;
25     dfn[x] = low[x] = ++sum;
26     a.push(x);
27     _in[x] = 1;
28     for(int i = head[x];i != -1; i = e[i].next) {
29         v = e[i].to;
30         if(!dfn[v]) {
31             tarjan(v);
32             low[x] = min(low[x],low[v]); 
33         }
34         else if(_in[v]) 
35             low[x] = min(low[x],dfn[v]);
36     }
37     if(dfn[x] == low[x]) {
38         csp++;
39         do {
40             v = a.top();
41             a.pop();
42             _in[v] = false;
43             num[csp]++;
44             belong[v] = csp; 
45         }
46         while(v != x);
47     }
48 }
49 
50 int main()
51 {
52     memset(head,-1,sizeof(head));
53     scanf("%d%d",&n,&m);
54     for(int i = 1;i <= m; i++) {
55         int x,y;
56         scanf("%d%d",&x,&y);
57         add(x,y);
58         e[i].pp = 0;
59     }
60     for(int i = 1;i <= n; i++) 
61         if(!dfn[i])
62             tarjan(i);
63     for(int i = 1;i <= n; i++) 
64         for(int j = head[i];j != -1; j = e[j].next) {
65             if(belong[e[j].to] != belong[i])
66                 outd[belong[i]]++;
67         }
68     int ans = -1;
69     for(int i = 1;i <= csp; i++) {
70         if(outd[i] == 0)
71             if(ans == -1)
72                 ans = num[i];
73             else{
74                 printf("0");
75                 return 0;
76             }
77     }
78     printf("%d",ans);
79     return 0;
80 }
原文地址:https://www.cnblogs.com/lipeiyi520/p/11440059.html