第一个答案是统计图中桥的个数
如果一个点-双连通分量中边的个数大于点的个数那么这个块中所有的边都是冲突的,累加到第二个答案中去。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 #include <stack> 8 #define MP make_pair 9 #define Ft first 10 #define Sd second 11 using namespace std; 12 13 typedef pair<int, int> PII; 14 15 const int maxn = 10000 + 10; 16 17 int n, m; 18 19 vector<int> G[maxn]; 20 21 vector<PII> bcc[maxn]; 22 stack<PII> S; 23 int pre[maxn], low[maxn], dfs_clock, bcc_cnt; 24 25 int ans1, ans2; 26 27 void dfs(int u, int fa) 28 { 29 low[u] = pre[u] = ++dfs_clock; 30 for(int i = 0; i < G[u].size(); i++) 31 { 32 int v = G[u][i]; 33 if(!pre[v]) 34 { 35 S.push(MP(u, v)); 36 dfs(v, u); 37 low[u] = min(low[u], low[v]); 38 39 if(low[v] >= pre[u]) 40 { 41 bcc_cnt++; 42 bcc[bcc_cnt].clear(); 43 for(;;) 44 { 45 PII x = S.top(); S.pop(); 46 bcc[bcc_cnt].push_back(x); 47 if(x.Ft == u && x.Sd == v) break; 48 } 49 if(low[v] > pre[u]) ans1++; //bridge 50 } 51 } 52 else if(v != fa && pre[v] < pre[u]) 53 { 54 S.push(MP(u, v)); 55 low[u] = min(low[u], pre[v]); 56 } 57 } 58 } 59 60 void find_bcc() 61 { 62 memset(pre, 0, sizeof(pre)); 63 dfs_clock = bcc_cnt = 0; 64 for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1); 65 } 66 67 bool vis[maxn]; 68 69 int main() 70 { 71 while(scanf("%d%d", &n, &m) == 2 && n) 72 { 73 for(int i = 0; i < n; i++) G[i].clear(); 74 while(m--) 75 { 76 int u, v; scanf("%d%d", &u, &v); 77 G[u].push_back(v); 78 G[v].push_back(u); 79 } 80 81 ans1 = ans2 = 0; 82 find_bcc(); 83 84 for(int i = 1; i <= bcc_cnt; i++) 85 { 86 memset(vis, false, sizeof(vis)); 87 int vertex = 0, sz = bcc[i].size(); 88 for(int j = 0; j < sz; j++) 89 { 90 PII x = bcc[i][j]; 91 if(!vis[x.Ft]) { vis[x.Ft] = true; vertex++; } 92 if(!vis[x.Sd]) { vis[x.Sd] = true; vertex++; } 93 } 94 if(sz > vertex) ans2 += sz; 95 } 96 97 printf("%d %d ", ans1, ans2); 98 } 99 100 return 0; 101 }