无向图求割点和连通块。
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 }