POJ 2942Knights of the Round Table(二分图判定+双连通分量)
Posted zhaop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2942Knights of the Round Table(二分图判定+双连通分量)相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <stack> 6 #include <vector> 7 using namespace std; 8 const int Max = 1010; 9 vector<int> G[Max], bcc[Max]; 10 int odd[Max], color[Max]; 11 int A[Max][Max]; 12 int pre[Max], iscut[Max], bccno[Max]; 13 int dfs_clock, bcc_cnt; 14 15 struct Edge 16 { 17 int u, v; 18 }; 19 stack<Edge> S; 20 int dfs(int u, int fa) 21 { 22 int lowu = pre[u] = ++dfs_clock; 23 int child = 0; 24 int Size = (int) G[u].size(); 25 for (int i = 0; i < Size; i++) 26 { 27 int v = G[u][i]; 28 Edge e; 29 e.u = u; 30 e.v = v; 31 if (!pre[v]) 32 { 33 S.push(e); 34 child++; 35 int lowv = dfs(v, u); 36 lowu = min(lowu, lowv); 37 if (lowv >= pre[u]) 38 { 39 iscut[u] = true; 40 ++bcc_cnt; 41 bcc[bcc_cnt].clear(); 42 for(;;) 43 { 44 Edge x = S.top(); 45 S.pop(); 46 if (bccno[x.u] != bcc_cnt) 47 { 48 bcc[bcc_cnt].push_back(x.u); 49 bccno[x.u] = bcc_cnt; 50 } 51 if (bccno[x.v] != bcc_cnt) 52 { 53 bcc[bcc_cnt].push_back(x.v); 54 bccno[x.v] = bcc_cnt; 55 } 56 if (x.u == u && x.v == v) 57 break; 58 } 59 } 60 } 61 else if (pre[v] < pre[u] && v != fa) 62 { 63 S.push(e); 64 lowu = min(lowu, pre[v]); 65 } 66 } 67 if (fa < 0 && child == 1) 68 iscut[u] = false; 69 return lowu; 70 } 71 void find_bcc(int n) 72 { 73 memset(pre, 0, sizeof(pre)); 74 memset(iscut, 0, sizeof(iscut)); 75 memset(bccno, 0, sizeof(bccno)); 76 dfs_clock = bcc_cnt = 0; 77 for (int i = 0; i < n; i++) 78 { 79 if (!pre[i]) 80 dfs(i, -1); 81 } 82 } 83 bool bipartite(int u, int b) 84 { 85 for (int i = 0; i < (int) G[u].size(); i++) 86 { 87 int v = G[u][i]; 88 if (bccno[v] != b) 89 continue; 90 if (color[v] == color[u]) 91 return false; 92 if (!color[v]) 93 { 94 color[v] = 3 - color[u]; 95 if (!bipartite(v, b)) 96 return false; 97 } 98 } 99 return true; 100 } 101 int main() 102 { 103 int n, m; 104 while (scanf("%d%d", &n, &m) != EOF) 105 { 106 if (n == 0 && m == 0) 107 break; 108 for (int i = 0; i <= n; i++) 109 G[i].clear(); 110 memset(A, 0, sizeof(A)); 111 for (int i = 0; i < m; i++) 112 { 113 int u, v; 114 scanf("%d%d", &u, &v); 115 u--; 116 v--; 117 A[u][v] = A[v][u] = 1; 118 } 119 for (int i = 0; i < n; i++) 120 { 121 for (int j = i + 1; j < n; j++) 122 { 123 if (!A[i][j]) 124 { 125 G[i].push_back(j); 126 G[j].push_back(i); 127 } 128 } 129 } 130 131 find_bcc(n); 132 133 // cout << bcc[3][0] << endl; 134 memset(odd, 0, sizeof(odd)); 135 for (int i = 1; i <= bcc_cnt; i++) 136 { 137 memset(color, 0, sizeof(color)); 138 for (int j = 0; j < (int) bcc[i].size(); j++) 139 bccno[ bcc[i][j] ] = i; 140 int u = bcc[i][0]; 141 color[u] = 1; 142 143 if (!bipartite(u, i)) 144 { 145 for (int j = 0; j < (int) bcc[i].size(); j++) 146 odd[ bcc[i][j] ] = 1; 147 } 148 } 149 int ans = n; 150 for (int i = 0; i < n; i++) 151 if (odd[i]) 152 ans--; 153 printf("%d\n", ans); 154 } 155 return 0; 156 }
以上是关于POJ 2942Knights of the Round Table(二分图判定+双连通分量)的主要内容,如果未能解决你的问题,请参考以下文章
poj2942 Knights of the Round Table
poj2942:Knights of the Round Table——题解
poj2942 Knights of the Round Table
POJ 2942Knights of the Round Table(二分图判定+双连通分量)