poj 2186 强连通入门题目

每头牛的梦想就是成为牛群中最受欢迎的牛。 在一群N(1 <= N <= 10,000)母牛中,

你可以得到M(1 <= M <= 50,000)有序的形式对(A,B),告诉你母牛A认为母牛 B很受欢迎。

由于流行是传递性的,如果A认为B很受欢迎,B认为C受欢迎,那么A也会认为C是
流行的,即使这不是输入中有序对明确规定的。

你的任务是计算每头奶牛认为受欢迎的奶牛数量。

水题 强连通入门题目。

 tarjin缩点  然后就变成一棵树,

然后就是求有多少个点的出度为0  

输入这个点里面包含的所有点,因为有缩点出来的

所有输出他的强连通分量

缩点后如果有多个出度为0的点,这样是不符合题意的,输出0

不联通 也是输出0

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 
 8 const int maxn = 1e5 + 10;
 9 int n, m, u, v, tot, top, cnt, flag;
10 struct node {
11     int v, next;
12 } edge[maxn];
13 int head[maxn], instack[maxn], s[maxn];
14 int dfn[maxn], low[maxn], belong[maxn];
15 void init() {
16     tot = cnt = top = flag = 0;
17     memset(head, -1, sizeof(head));
18     memset(dfn, 0, sizeof(dfn));
19     memset(instack, 0, sizeof(instack));
20 }
21 void add(int u, int v) {
22     edge[tot].v = v;
23     edge[tot].next = head[u];
24     head[u] = tot++;
25 }
26 void tarjin(int v) {
27     dfn[v] = low[v] = ++flag;
28     instack[v] = 1;
29     s[top++] = v;
30     for (int i = head[v] ; i != -1 ; i = edge[i].next) {
31         int j = edge[i].v;
32         if (!dfn[j]) {
33             tarjin(j);
34             low[v] = min(low[v], low[j]);
35         } else if (instack[j]) low[v] = min(low[v], dfn[j]);
36     }
37     if (dfn[v] == low[v]) {
38         cnt++;
39         int t;
40         do {
41             t = s[--top];
42             instack[t] = 0;
43             belong[t] = cnt;
44         } while(t != v) ;
45     }
46 }
47 int du[maxn];
48 void solve() {
49     for (int i = 1 ; i <= n ; i++)
50         if (!dfn[i]) tarjin(i);
51 }
52 int main() {
53     while(scanf("%d%d", &n, &m) != EOF) {
54         if (n == 0 && m == 0) break;
55         init();
56         memset(du, 0, sizeof(du));
57         for (int i = 0 ; i < m ; i++) {
58             scanf("%d%d", &u, &v);
59             add(u, v);
60         }
61         for (int i = 1  ; i <= n ; i++)
62             if (!dfn[i]) tarjin(i);
63         for (int i = 1 ; i <= n ; i++) {
64             for (int j = head[i] ; ~j; j = edge[j].next ) {
65                 if (belong[edge[j].v] != belong[i]) du[belong[i]]++;
66             }
67         }
68         int ansrt, zero = 0;
69         for (int i = 1 ; i <= cnt ; i++) {
70             if (!du[i]) {
71                 ansrt = i;
72                 zero++;
73             }
74         }
75         if (zero == 1) {
76             int ans = 0;
77             for (int i = 1 ; i <= n ; i++) {
78                 if (belong[i] == ansrt) ans++;
79             }
80             printf("%d
", ans);
81         } else printf("0
");
82     }
83     return 0;
84 }
原文地址:https://www.cnblogs.com/qldabiaoge/p/9072646.html