POJ_2186 Popular Cows (Tarjan 强连通分量 缩点)

  将强连通分量进行缩点,然后找缩点后的图中出度为0的缩点所包含的结点数,就是最后结果。如果出现多个出度为0的缩点,则表示不存在所求的点。

渣代码:

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <stack>
5
6 using namespace std;
7
8 const int M = 50010;
9 const int N = 10010;
10
11 struct node {
12 int to;
13 int next;
14 } g[M];
15
16 int head[N], blong[N], val[N];
17 int dfn[N], low[N], out[N];
18 int t, ind, cnt;
19 bool vis[N];
20
21 stack<int> s;
22
23 void init() {
24 memset(head, 0, sizeof(head));
25 memset(blong, 0, sizeof(blong));
26 memset(dfn, 0, sizeof(dfn));
27 memset(low, 0, sizeof(low));
28 memset(vis, 0, sizeof(vis));
29 memset(val, 0, sizeof(val));
30 memset(out, 0, sizeof(out));
31
32 t = 1; ind = cnt = 0;
33 }
34
35 void add(int u, int v) {
36 g[t].to = v; g[t].next = head[u]; head[u] = t++;
37 }
38
39 void tarjan(int u) {
40 int v, i;
41 vis[u] = true;
42 s.push(u);
43 low[u] = dfn[u] = ++ind;
44 for(i = head[u]; i; i = g[i].next) {
45 v = g[i].to;
46 if(!dfn[v]) {
47 tarjan(v);
48 low[u] = min(low[u], low[v]);
49 } else if(vis[u]) {
50 low[u] = min(low[u], dfn[v]);
51 }
52 }
53 if(low[u] == dfn[u]) {
54 cnt++;
55 do {
56 v = s.top(); s.pop();
57 blong[v] = cnt;
58 val[cnt]++;
59 //printf("%d %d\n", v, cnt);
60 } while(v != u);
61 }
62 }
63
64 int main() {
65 //freopen("data.in", "r", stdin);
66
67 int n, m, a, b;
68 int i, j, v;
69 while(~scanf("%d%d", &n, &m)) {
70 init();
71 for(i = 1; i <= m; i++) {
72 scanf("%d%d", &a, &b);
73
74 add(a, b);
75 }
76 for(i = 1; i <= n; i++) {
77 if(!dfn[i]) tarjan(i);
78 }
79
80 for(i = 1; i <= n; i++) {
81 for(j = head[i]; j; j = g[j].next) {
82 v = g[j].to;
83 //printf("%d %d\n", i, v);
84 if(blong[i] != blong[v])
85 out[blong[i]]++;
86 }
87 }
88 int cou = 0, f = 1;
89 for(i = 1; i <= cnt; i++) {
90 if(!out[i]) {cou++; f = i;}
91 }
92 if(cou > 1) printf("0\n");
93 else printf("%d\n", val[f]);
94 }
95 return 0;
96 }



原文地址:https://www.cnblogs.com/vongang/p/2346833.html