poj2186 Popular Cows

Posted 王宜鸣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2186 Popular Cows相关的知识,希望对你有一定的参考价值。

题意:

给定一个有向图,求有多少个顶点是由任何顶点出发都可达的。
顶点数<= 10,000,边数 <= 50,000

思路:

Korasaju算法把图进行强连通分量分解,在分解的同时得到各个强连通分量拓扑序。唯一可能成为解的就是拓扑序最后的强连通分量,最后再检查这个强连通分量是否能从各个顶点均可达即可。

实现:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 vector<int> G[10005], G_t[10005], res;
 8 int n, m, x, y, cmp[10005];
 9 bool vis[10005];
10 void dfs(int x)
11 {
12     vis[x] = true;
13     for (int i = 0; i < G[x].size(); i++)
14     {
15         if (!vis[G[x][i]])
16             dfs(G[x][i]);
17     }
18     res.push_back(x);
19 }
20 
21 void rdfs(int x, int k)
22 {
23     vis[x] = true;
24     cmp[x] = k;
25     for (int i = 0; i < G_t[x].size(); i++)
26     {
27         if (!vis[G_t[x][i]])
28         {
29             rdfs(G_t[x][i], k);
30         }
31     }
32 }
33 
34 int main()
35 {
36     while (cin >> n >> m)
37     {
38         for (int i = 1; i <= n; i++)
39         {
40             G[i].clear();
41             G_t[i].clear();
42         }
43         res.clear();
44         for (int i = 0; i < m; i++)
45         {
46             scanf("%d %d", &x, &y);
47             G[x].push_back(y);
48             G_t[y].push_back(x);
49         }
50         memset(vis, 0, sizeof(vis));
51         for (int i = 1; i <= n; i++)
52         {
53             if (!vis[i])
54                 dfs(i);
55         }
56         memset(vis, 0, sizeof(vis));
57         int k = 0;
58         for (int i = res.size() - 1; i >= 0; i--)
59         {
60             if (!vis[res[i]])
61             {
62                 rdfs(res[i], k++);
63             }
64         }
65         int cnt = 0, tmp = 0;
66         for (int i = 1; i <= n; i++)
67         {
68             if (cmp[i] == k - 1)
69             {
70                 cnt++;
71                 tmp = i;
72             }
73         }
74         memset(vis, 0, sizeof(vis));
75         rdfs(tmp, 0);
76         for (int i = 1; i <= n; i++)
77         {
78             if (!vis[i])
79             {
80                 cnt = 0;
81                 break;
82             }
83         }
84         printf("%d\n", cnt);
85     }
86     return 0;
87 }

总结:

有向图进行进行强连通分量分解并缩点之后可以得到一个DAG。

如果有多于一个出度为0的缩点则解为0。

 

以上是关于poj2186 Popular Cows的主要内容,如果未能解决你的问题,请参考以下文章

POJ2186 Popular Cows

Popular Cows(POJ 2186)

Poj2186Popular Cows

POJ 2186 Popular Cows

POJ 2186 Popular Cows

Popular Cows POJ - 2186(强连通分量)