POJ 2942 Knights of the Round Table [二分图染色][点双连通分量]
2017-07-10 10:29
591 查看
被震惊到了!没想到图上的知识居然那么玄妙。
归纳出两点:
1.对于一个连通分量内,若二分图染色后为二分图,则图内全为偶环,无奇环。
2.对于一个连通分量内,若二分图染色后不为二分图,则图内全为奇环,无偶环。
证明我还是画一画图吧。
对于结论1。
先来个二分图
然后选择其中的一个偶环,
我们发现根据二分图的性质,从左道右就必定能够从右到左,那么这就不是个奇环了。
对于结论2。
我们发现在一个连通分量中,若能找到一个奇环,对于任意一个点连接图上任意两个点都一定能够都到包含着个点的一个奇环、一个偶环,易证。
所以说哈哈啦。
code实现也是很简单的。
一个二分图染色,一个Tarjan。
归纳出两点:
1.对于一个连通分量内,若二分图染色后为二分图,则图内全为偶环,无奇环。
2.对于一个连通分量内,若二分图染色后不为二分图,则图内全为奇环,无偶环。
证明我还是画一画图吧。
对于结论1。
先来个二分图
然后选择其中的一个偶环,
我们发现根据二分图的性质,从左道右就必定能够从右到左,那么这就不是个奇环了。
对于结论2。
我们发现在一个连通分量中,若能找到一个奇环,对于任意一个点连接图上任意两个点都一定能够都到包含着个点的一个奇环、一个偶环,易证。
所以说哈哈啦。
code实现也是很简单的。
一个二分图染色,一个Tarjan。
//随便贴一份代码吧。。。。 #include<iostream> #include<cstdio> #include<cstring> #define clr(x) memset((x),0,sizeof(x)) using namespace std; const int N=1010; const int M=1000010; int n,m,i,j,k,l; int head ,next[M],list[M],tot,caset; int dfn ,low ,sta ,sta_tot,cnt__index,bfn ,bfn_tot,col ; int aa ,ans ; void add(int a,int b){ tot++; list[tot]=b; next[tot]=head[a]; head[a]=tot; } bool dfs(int x,int c){ col[x]=c; for(int i=head[x];i;i=next[i]) if(bfn[list[i]]==bfn_tot){ if(col[list[i]]==c)return false; else if(col[list[i]]!=(c^1)&&dfs(list[i],c^1)==false)return false; } return true; } void colour(int x){ ans[x]=1;bfn[x]=-1; for(int i=head[x];i;i=next[i]) if(bfn[list[i]]==bfn_tot)colour(list[i]); return; } int tarjan(int x,int fa){ int i,j,k; dfn[x]=low[x]=++cnt__index; sta[++sta_tot]=x; for(int i=head[x];i;i=next[i]) if(i!=fa){ if(!dfn[list[i]]){ low[x]=min(low[x],tarjan(list[i],i^1)); if(low[list[i]]>=dfn[x]){ bfn_tot++; while(sta[sta_tot+1]!=list[i]) bfn[sta[sta_tot--]]=bfn_tot; bfn[sta[sta_tot]]=bfn_tot; bfn[x]=bfn_tot; if(!dfs(x,x<<1))colour(x); } } else low[x]=min(low[x],dfn[list[i]]); } return low[x]; } int main(){ while(scanf("%d%d",&n,&m),n||m){ tot=1;cnt__index=sta_tot=bfn_tot=0; clr(ans),clr(col),clr(head),clr(bfn),clr(dfn); caset++; for(i=1;i<=m;i++){ scanf("%d%d",&j,&k); aa[j][k]=caset; aa[k][j]=caset; } for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) if(aa[i][j]!=caset) {add(i,j);add(j,i);} for(i=1;i<=n;i++) if(!dfn[i])tarjan(i,0); k=0; for(i=1;i<=n;i++) if(!ans[i]||!head[i])k++; printf("%d\n",k); } return 0; }
相关文章推荐
- 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)
- POJ2942 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 【无向图求BCC + 黑白染色判断二分图】
- poj 2942 Knights of the Round Table 补图+点双连通分量+判定二分图
- poj 2942 Knights of the Round Table Tarjan求点双联通分量+黑白染色二分图判断
- POJ 2942:Knights of the Round Table tarjan点双联通分量 二分图染色找奇环
- 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(Tarjan求点双联通分量+DFS对环染色)
- poj 2942 Knights of the Round Table 点-双连通分量 图论综合题
- 【POJ】2942 Knights of the Round Table(双连通分量)
- poj 2942 Knights of the Round Table 边连通分量+染色法