poj 2942--Knights of the Round Table (点双连通分量)
来源:互联网 发布:sai绘画软件手机版 编辑:程序博客网 时间:2024/06/11 15:47
题目链接点这里
有个奇特但显然的结论,如何一个双联通分量中有奇圈,那这个双联通分量中的所有点都都可以处于奇圈上
证明的话可以这样
任选一个点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;}
0 0
- poj 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 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(边双连通分量)
- 逆向安全基础之IDA使用简介
- 一个有意思的问题
- maven仓库国内镜像
- H265介绍
- 多个项目使用多个jdk的问题。
- poj 2942--Knights of the Round Table (点双连通分量)
- es6中的Number.isNaN(),判断是否是NaN
- 2017年计划
- 根据内容获取UIWebView的高度
- 遇到问题----java----myeclipse或者eclipse发布的项目时配置文件不更新或者无配置文件
- 异常(二)
- 支付宝问题:
- 开源项目Lottie的基本介绍(一)
- 三大WEB服务器对比分析Apache、Lighttpd、Nginx