LA 3523
2013-02-18 16:29
162 查看
#include<stdio.h> #include<string.h> const int N = 1010; const int M = 3000000; struct Edge { int u, v, next; Edge() {} Edge(int u, int v, int next) : u(u), v(v), next(next) {} }E[M]; int head , tot; void addEdge(int u, int v) { E[tot] = Edge(u, v, head[u]); head[u] = tot++; E[tot] = Edge(v, u, head[v]); head[v] = tot++; } int pre , iscut , bccno , dfs_colock, bcc_cnt, bcc , bcc_size ; Edge S[M]; int ST; int color ; bool bipartite(int u, int b) { for(int i = head[u]; i != -1; i = E[i].next) { int v = E[i].v; if(bccno[v] != b) continue; if(color[v] == color[u]) return false; if(!color[v]) { color[v] = 3 - color[u]; if(!bipartite(v, b)) return false; } } return true; } int min(int a, int b) { return a < b ? a : b; } int dfs(int u, int fa) { int lowu = pre[u] = ++dfs_colock; int child = 0; for(int i = head[u]; i != -1; i = E[i].next) { int v = E[i].v; Edge e = Edge(u, v, -1); if(!pre[v]) { S[++ST] = e; child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv >= pre[u]) { iscut[u] = true; bcc_cnt++; bcc_size[bcc_cnt] = 0; while(1) { Edge x = S[ST--]; if(bccno[x.u] != bcc_cnt) { bcc[bcc_cnt][bcc_size[bcc_cnt]++] = x.u; bccno[x.u] = bcc_cnt; } if(bccno[x.v] != bcc_cnt) { bcc[bcc_cnt][bcc_size[bcc_cnt]++] = x.v; bccno[x.v] = bcc_cnt; } if(x.u == u && x.v == v) break; } } } else if(pre[v] < pre[u] && v != fa) { S[++ST] = e; lowu = min(lowu, pre[v]); } } if(fa < 0 && child == 1) iscut[u] = 0; return lowu; } void find_bcc(int n) { memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); memset(bccno, 0, sizeof(bccno)); dfs_colock = bcc_cnt = 0; for(int i = 0; i < n; ++i) if(!pre[i]) dfs(i, -1); } int A ; int main() { int kase = 0, n, m; while(scanf("%d%d", &n, &m) && n) { memset(head, -1, sizeof(head)); memset(A, 0, sizeof(A)); for(int i = 0; i < m; ++i) { int u, v; scanf("%d%d", &u, &v); u--; v--; A[u][v] = A[v][u] = 1; } for(int i = 0; i < n; ++i) for(int j = i + 1; j < n; ++j) if(!A[i][j]) addEdge(i, j); find_bcc(n); int odd ={0}; for(int i = 1; i<= bcc_cnt; ++i) { memset(color, 0, sizeof(color)); for(int j = 0; j < bcc_size[i]; ++j) bccno[bcc[i][j]] = i; int u = bcc[i][0]; color[u] = 1; if(!bipartite(u, i)) for(int j = 0; j < bcc_size[i]; ++j) odd[bcc[i][j]] = 1; } int ans = n; for(int i = 0; i < n; ++i) if(odd[i]) ans--; printf("%d\n", ans); } return 0; }
相关文章推荐
- LA 3523 圆桌骑士
- LA 3523 Knights of the Round Table 边双连通分量+二分图判定
- LA3523——无向图的点双连通分量
- 双连通分量,二分图(圆桌骑士,LA 3523)
- LA 3523 圆桌骑士 (双连通)
- LA 3523 圆桌骑士
- LA 3523 圆桌骑士(二分图染色+点双连通分量)
- LA 3523 tarjian求双连通分量+二分判奇圈
- LA 3523 - Knights of the Round Table
- LA 3523(双连通分量,判断二分图)
- LA 3523 Knights of the Round Table(点双连通分量+二分图判断)
- 信息安全--三:BLP模型(Bell-La Padula模型)
- Linux中的.so .a .la文件的含义
- C'est la vie
- 关于libtool: link: warning: libmemcached.la seems to be moved
- 高效开发乘胜追击-Zoomla!逐浪CMS1.2版发布
- Pourquoi sont blessés avant la sécheresse agriculteurs
- Alizee-La_isla_bonita
- 现实世界的Windows Azure:采访伟创力公司运营IT总监Husam Laswi
- linux下的so、o、lo、a、la文件有什么区别