POJ 2942 Knights of the Round Table(点双联通+二分图+染色)
来源:互联网 发布:写英语论文的软件 编辑:程序博客网 时间:2024/04/19 20:12
大意:m个关系的人之间不能再圆桌上坐在相邻的位置上。并且人数为奇数,问至少踢出多少人能够开会。
思路:因为人是围着圆桌坐,所以每人的度肯定是2,即度为1和0(单独一人)的都要被踢除。那么可以抽象为点的双联通。在出现桥的时候(即度数为1)将该联通块的人都统计下来,判断是不是奇环(二分染色)(PS:说明为啥不能直接统计个数判断奇环呢?既然是点的双联通那么一定是环,是不是能够直接判断当前的人数就能下是奇环的定论呢? 答案是否定的!因为联通块可能由多个奇环组成!)
#include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define LL int#define inf 0x3f3f3f3f#define eps 1e-8#include<vector>#define ls l,mid,rt<<1#define rs mid+1,r,rt<<1|1using namespace std;const int Ma = 1100;struct node{ int to,w,next;}q[Ma*Ma];bool mp[1100][1100];int head[Ma*Ma],dfn[Ma],stk[Ma*5],vis[Ma],low[Ma],tmp[Ma],col[Ma],part[Ma];int cnt,top,tim,scc,sum,n,ans,mark[Ma];void Add(int a,int b){ q[cnt].to = b; q[cnt].next = head[a]; head[a] = cnt++;}void init(){ ans = scc = cnt = top = 0; tim = 1; memset(head,-1,sizeof(head)); memset(mp,false,sizeof(mp)); for(int i = 1;i <= n;++ i){ low[i] = dfn[i] = 0; vis[i]=mark[i] = 0; }}bool ser(int u,int co){ col[u] = co; for(int i=head[u];~i;i=q[i].next){ int v = q[i].to; if(!part[v]) continue; if(col[v] == co) return true; if(!col[v] && ser(v,-co)) return true; } return false;}void Judge(){ memset(part,0,sizeof(part)); memset(col,0,sizeof(col)); for(int i = 0;i < sum;++ i){ part[tmp[i] ] = 1; } if(ser(tmp[0],1)){ for(int i = 0;i < sum;++ i) mark[tmp[i] ] = 1; }}void Tarjan(int u,int To){ low[u] = dfn[u] = tim++; vis[u] = 1; stk[top++] = u; for(int i = head[u]; ~i ; i = q[i].next){ int v = q[i].to; if(i == (To^1)) continue; if(!vis[v]){ Tarjan(v,i); low[u] = min(low[u],low[v]); if(low[v] >= dfn[u]){ sum = 0; tmp[sum++] = u; stk[top] = -1; while( stk[top] != v ){ tmp[sum++] = stk[--top]; } Judge(); } } else low[u] = min(low[u],dfn[v]); }}int main(){ int m,i,j,k,a,b,c,cla; while(~scanf("%d%d",&n,&m)){ if(!n&&!m) break; init(); for(i = 0;i < m;++ i){ scanf("%d%d",&a,&b); mp[b][a] = mp[a][b] = true; } for(i = 1;i <= n;++ i) for(j = i+1;j <= n;++ j) if(!mp[i][j]) Add(i,j), Add(j,i); for(i = 1;i <= n;++ i) if(!dfn[i]) Tarjan(i,-1); for(i = 1;i <= n;++ i) if(mark[i]) ans++; printf("%d\n",n-ans); } return 0;}
0 0
- POJ 2942 Knights of the Round Table(点双联通+二分图+染色)
- 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 圆桌骑士
- #UVALive3523#Knights of the Round Table(点双连通分量 + 二分图染色判奇环)
- 【poj 2942 】 Knights of the Round Table 【tarjan求bcc+黑白染色判二分图】
- POJ 2942 Knights of the Round Table(【点双连通分量】+【二分图判定】)
- POJ 2942 Knights of the Round Table 点双联通分量
- poj2942—Knights of the Round Table(点双联通分量的求解+染色法判断奇圈)
- uva1364 - 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 【无向图求BCC + 黑白染色判断二分图】
- fedora 的学习历程
- 最大子段和的以为与二维求解
- 空心三角形(图形的输出)c语言
- 十七、代理设计模式
- linux下的简单文件服务器和客户端程序
- POJ 2942 Knights of the Round Table(点双联通+二分图+染色)
- 莫比乌斯反演模板
- SQL中 group by 1, order by 1 语句是什么意思
- Object-c------计算代码行数小demo
- Android View 事件分发机制梳理
- Qt应用程序以管理员身份启动
- 16.5.6-7学习内容
- LeetCode-46&47.Permutations
- 关于java.split问题