Tarjan解无向图的割点和桥,参考白书。
1 /* 4587 */ 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 5005 11 12 vector<int> vc[MAXN]; 13 int dfs_clock; 14 int cnt[MAXN]; 15 int pre[MAXN]; 16 int n, m, cur; 17 18 int Tarjan(int u, int fa) { 19 int i, j, k, v; 20 int lowu, lowv; 21 int child = 0; 22 23 lowu = pre[u] = ++dfs_clock; 24 for (i=0; i<vc[u].size(); ++i) { 25 v = vc[u][i]; 26 if (v==fa || v==cur) 27 continue; 28 if (!pre[v]) { 29 ++child; 30 lowv = Tarjan(v, u); 31 lowu = min(lowu, lowv); 32 if (lowv >= pre[u]) 33 ++cnt[u]; 34 } else if (pre[v] < pre[u]) 35 lowu = min(lowu, pre[v]); 36 } 37 if (fa < 0) 38 cnt[u] = child - 1; 39 return lowu; 40 } 41 42 void init() { 43 dfs_clock = 0; 44 memset(cnt, 0, sizeof(int)*n); 45 memset(pre, 0, sizeof(int)*n); 46 } 47 48 int main() { 49 int i, j, k; 50 int ans; 51 52 #ifndef ONLINE_JUDGE 53 freopen("data.in", "r", stdin); 54 #endif 55 56 while (scanf("%d %d", &n, &m)!=EOF) { 57 for (i=0; i<n; ++i) 58 vc[i].clear(); 59 while (m--) { 60 scanf("%d %d", &i, &j); 61 vc[i].push_back(j); 62 vc[j].push_back(i); 63 } 64 ans = 0; 65 for (cur=0; cur<n; ++cur) { 66 init(); 67 k = 0; 68 for (i=0; i<n; ++i) { 69 if (i!=cur && !pre[i]) { 70 ++k; 71 Tarjan(i, -1); 72 } 73 } 74 for (i=0; i<n; ++i) 75 if (i!=cur) 76 ans = max(ans, k+cnt[i]); 77 } 78 printf("%d ", ans); 79 } 80 81 return 0; 82 }