poj 2942--Knights of the Round Table (点双连通分量)
2017-02-07 17:24
429 查看
题目链接点这里
有个奇特但显然的结论,如何一个双联通分量中有奇圈,那这个双联通分量中的所有点都都可以处于奇圈上
证明的话可以这样
任选一个点x,如果x点在那个奇圈上,显然成立
如果不是,我们可以从x点,构造2条路径到奇圈上的不同两个a,b点。显然a,b之间的在奇圈上的路径,有2条,分别为奇数长度和偶数长度。
如果xa+xb为奇数,那么就选取ab的偶数路径,反之选取奇数路径。就一定可以构造一个经过x的奇圈
有个奇特但显然的结论,如何一个双联通分量中有奇圈,那这个双联通分量中的所有点都都可以处于奇圈上
证明的话可以这样
任选一个点x,如果x点在那个奇圈上,显然成立
如果不是,我们可以从x点,构造2条路径到奇圈上的不同两个a,b点。显然a,b之间的在奇圈上的路径,有2条,分别为奇数长度和偶数长度。
如果xa+xb为奇数,那么就选取ab的偶数路径,反之选取奇数路径。就一定可以构造一个经过x的奇圈
#include<iostream> #include<map> #include<stdio.h> #include<bitset> #include<stack> #include<algorithm> #include<queue> #include<set> #include<string.h> #include<string> #include<vector> #define MX 1111 #define INF 0x3f3f3f3f #define mem(x,y) memset(x,y,sizeof(x)) #define FIN freopen("input.txt","r",stdin) using namespace std; int n,m; int head[MX],cnt; struct Edge { int nxt,to; } edge[2*MX*MX]; void edge_init() { mem(head,-1); cnt=0; } void edge_add(int a,int b) { edge[cnt].to=b; edge[cnt].nxt=head[a]; head[a]=cnt++; } /* int low[MX],pre[MX],dfs_block; bool iscut[MX]; int dfs(int u,int fa) { int lowu=pre[u]=++dfs_block; int child=0; for(int i=head[u]; ~i; i=edge[i].nxt) { int v=edge[i].to; if(!pre[v]) { child++; int lowv=dfs(v,u); lowu=min(lowu,lowv); } else if(pre[v]<pre[u]&&v!=fa) lowu=min(lowu,pre[v]); } if(lowu>=pre[u]) iscut[u]=1; if(fa<0&&child==1) iscut[u]=0; return low[u]=lowu; } void cut_v() { dfs_block=0; mem(pre,0); mem(low,0); mem(iscut,0); for(int i=1; i<=n; i++) if(!pre[i]) dfs(i,-1); } */ int low[MX],pre[MX],bccno[MX],dfs_block,bcc_cnt; bool iscut[MX]; //bitset<MX> bcc[MX]; vector<int>bcc[MX]; stack<int> S; int dfs(int u,int fa) { int lowu=pre[u]=++dfs_block; int child=0; for(int i=head[u]; ~i; i=edge[i].nxt) { int v=edge[i].to; if(!pre[v]) { S.push(i); child++; int lowv=dfs(v,u); lowu=min(lowu,lowv); if(lowv>=pre[u]) { iscut[u]=1; bcc_cnt++; //bcc[bcc_cnt].reset(); bcc[bcc_cnt].clear(); while(1) { int w=S.top(); S.pop(); int vv=edge[w].to,uu=edge[w^1].to; if(bccno[uu]!=bcc_cnt) { //bcc[bcc_cnt][uu]=1; bcc[bcc_cnt].push_back(uu); bccno[uu]=bcc_cnt; } if(bccno[vv]!=bcc_cnt) { // bcc[bcc_cnt][vv]=1; bcc[bcc_cnt].push_back(vv); bccno[vv]=bcc_cnt; } if(vv==v&&uu==u) break; } } } else if(pre[v]<pre[u]&&v!=fa) { lowu=min(lowu,pre[v]); } } if(fa<0&&child==1) iscut[u]=0; return low[u]=lowu; } void find_bcc() { dfs_block=bcc_cnt=0; mem(pre,0); mem(low,0); mem(iscut,0); mem(bccno,0); for(int i=1; i<=n; i++) if(!pre[i]) dfs(i,-1); } bool isok[MX][MX]; inline int read() { int ret=0,c,f=1; for(c=getchar(); !(isdigit(c)||c=='-'); c=getchar()); if(c=='-') f=-1,c=getchar(); for(; isdigit(c); c=getchar()) ret=ret*10+c-'0'; if(f<0) ret=-ret; return ret; } bool is[MX]; int color[MX]; bool color_dfs(int u,int col,int w) { if((color[u]|1)!=(col|1)) color[u]=-1; else if(color[u]!=-1&& color[u]!=col) return 0; if(color[u]!=-1) return 1; color[u]=col; //cout<<u<<endl; for(int i=head[u]; ~i; i=edge[i].nxt) { int v=edge[i].to; if(!bcc[w][v]) continue;// cout<<u<<" "<<v<<endl; if(color_dfs(v,col^1,w)==0) return 0; } return 1; } void ok(int u,int w) { if(is[u]) return; is[u]=1; for(int i=head[u]; ~i; i=edge[i].nxt) { int v=edge[i].to; if(!bcc[w][v]) continue; ok(v,w); } return; } int main() { FIN; while(scanf("%d%d",&n,&m)==2&&n) { edge_init(); mem(isok,1); for(int i=1; i<=m; i++) { int a,b; a= read(),b=read(); if(a>b) swap(a,b); isok[a][b]=0; } for(int i=1; i<=n; i++)for(int j=1; j<i; j++) if(isok[j][i]) edge_add(i,j),edge_add(j,i); find_bcc(); mem(is,0); int w=0; mem(color,-1); for(int i=1; i<=n; i++) if(color[i]==-1) { if(!color_dfs(i,w,bccno[i])) ok(i,bccno[i]); w+=2; } int cnnt=0; for(int i=1; i<=n; i++) if(!is[i]) { cnnt++; } printf("%d\n",cnnt); } return 0; }
相关文章推荐
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
- 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)
- poj2942 Knights of the Round Table,点双连通分量,奇环判断
- POJ-2942 Knights of the Round Table 双连通分量[推荐]
- poj 2942--Knights of the Round Table (点的双连通分量)
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
- POJ 2942 Knights of the Round Table 边双连通分量求解
- POJ 2942 Knights of the Round Table 边双连通分量求解
- POJ 2942 Knights of the Round Table(【点双连通分量】+【二分图判定】)
- poj 2942 Knights of the Round Table 点-双连通分量 图论综合题
- poj 2942 Knights of the Round Table 补图+点双连通分量+判定二分图
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
- POJ 2942 Knights of the Round Table (点双连通分量)
- POJ 2942 Knights of the Round Table [二分图染色][点双连通分量]
- poj 2942 Knights of the Round Table(边双连通分量)
- POJ 2942 Knights of the Round Table(双连通分量)
- poj 2942 Knights of the Round Table(点双连通分量)
- POJ 2942--Knights of the Round Table(双连通分量)
- 【POJ】2942 Knights of the Round Table(双连通分量)
- POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)