【POJ】2117 Electricity

无向图求割点和连通块。

 1 /* POJ2117 */
 2 #include <iostream>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <cstdio>
 6 #include <cstring>
 7 #include <cstdlib>
 8 using namespace std;
 9 
10 #define MAXN 10005
11 
12 vector<int> vc[MAXN];
13 int low[MAXN], pre[MAXN];
14 int n, m;
15 int dfs_clock, ans, link;
16 
17 void init() {
18     int i;
19     
20     for (i=0; i<n; ++i)
21         vc[i].clear();
22     
23     memset(pre, 0, sizeof(int)*n);
24     dfs_clock = ans = link = 0;
25 }
26 
27 void tarjan(int u, int fa) {
28     int i, j, k, v;
29     int child = 0;
30     int cnt = 0;
31     
32     pre[u] = low[u] = ++dfs_clock;
33     for (i=0; i<vc[u].size(); ++i) {
34         v = vc[u][i];
35         if (!pre[v]) {
36             ++child;
37             tarjan(v, u);
38             low[u] = min(low[u], low[v]);
39             if (low[v] >= pre[u]) {
40                 ++cnt;
41             }
42         } else if (pre[v]<pre[u] && v!=fa){
43             low[u] = min(low[u], pre[v]);
44         }
45     }
46     if (fa == -1) {
47         if (child > 1)
48             ans = max(ans, child-1);
49     } else {
50         ans = max(ans, cnt);
51     }
52 }
53 
54 int main() {
55     int i, j, k;
56     
57     #ifndef ONLINE_JUDGE
58         freopen("data.in", "r", stdin);
59         freopen("data.out", "w", stdout);
60     #endif
61     
62     while (scanf("%d %d",&n,&m)!=EOF && (n||m)) {
63         if (m == 0) {
64             printf("%d
", n-1);
65             continue;
66         }
67         init();
68         for (i=0; i<m; ++i) {
69             scanf("%d %d", &j, &k);
70             vc[j].push_back(k);
71             vc[k].push_back(j);
72         }
73         for (i=0; i<n; ++i) {
74             if (!pre[i]) {
75                 ++link;
76                 tarjan(i, -1);
77             }
78         }
79         printf("%d
", ans+link);
80     }
81     
82     return 0;
83 }
原文地址:https://www.cnblogs.com/bombe1013/p/4356621.html