题意:在亚瑟王的圆桌骑士团中,某些骑士两两之间相互憎恨,这样一来他们开会的时候边不能相邻的坐着。即肯定存在某些人不能参加会议。假如一个骑士所有的会议都不能出席,那么他就会被驱逐。现在已知那些骑士之间相互憎恨,求最少要驱逐多少名骑士。(开会时人数必需>=3且为奇数)
题解:建图时,对互相不憎恨的两人之间连一条边。对任意一名骑士来说,他要能出席某次会议则他左右的人都不能与他互相憎恨。将每次参加会议的所有人(不一定是整个骑士团,只需人数>=3且为奇数)看做一个点双联通分量,那么每个点都至少有两个点与他相邻。即需要保证双联通分量中存在奇圈。因为只要点双连通分量中存在奇圈,那么这个分量中所有的点都可以出现在奇圈上。求奇圈时可以用到这样一个性质,一个图是二分图当且仅当图中不存在奇圈。那么我们只需判断一个图是否是二分图就可以判断此图存在奇圈,可以用交替染色。

#include <iostream>
using namespace std;#define N 1005
#define min(a,b) (a<b?a:b)int n, m;
int size, id, scc;
int color[N], head[N];
int low[N], dfn[N], block[N];
int stack[N], temp[N], top, cnt; // temp 是一个临时的栈,存储点双连通分支
bool map[N][N], expell[N], instack[N];  // expell[i]==true表示i需要被驱逐
struct { int v, next; } edge[N*1000];bool odd_cycle ( int u, int clr ) //判断是否存在奇圈
{color[u] = clr;for ( int i = head[u]; i; i = edge[i].next ){int v = edge[i].v;if ( block[v] == scc ){if ( color[v] && color[v] == color[u] ) return true;if ( !color[v] && odd_cycle (v, -clr) )return true;}}return false;
}void Tarjan ( int u, int father )
{int v, t;stack[++top] = u;instack[u] = true;dfn[u] = low[u] = ++id;for ( int i = head[u]; i; i = edge[i].next ){v = edge[i].v;if ( v == father ) continue;if ( ! dfn[v] ){Tarjan ( v, u );low[u] = min ( low[u], low[v] );if ( low[v] >= dfn[u] )  // u是割点{scc++;do {t = stack[top--];instack[t] = false;block[t] = scc;temp[++cnt] = t; //出栈的同时把所有的点记录在temp中,即用temp来储存双连通分支内所有的点} while ( t != v ); //注意不要把u出栈,因为一个割点可能属于不同的双联通分支temp[++cnt] = u; // 割点u属于不同的双联通分支,所以它必然也属于tempmemset(color,0,sizeof(color)); // 所有颜色置为0if ( cnt >= 3 && odd_cycle(u,1) ) // 当temp中存在奇圈,那么temp中的所有人都可以留下{while ( cnt != 0 )expell[temp[cnt--]] = false;}else cnt = 0; }}else if ( instack[v] )low[u] = min ( low[u], dfn[v] );}
}void initial()
{top = cnt = 0;size = id = scc = 0;memset(map,0,sizeof(map));for ( int i = 1; i <= n; i++ ){expell[i] = true; instack[i] = false;dfn[i] = low[i] = block[i] = head[i] = 0;}
}void add ( int u, int v )
{size++;edge[size].v = v;edge[size].next = head[u];head[u] = size;
}int main()
{int u, v, i, j;while ( scanf("%d%d",&n,&m) && (m+n) ){initial();while ( m-- ){scanf("%d%d",&u,&v);map[u][v] = map[v][u] = true;}for ( i = 1; i <= n; i++ )for ( j = i+1; j <= n; j++ )if ( ! map[i][j] )add(i,j), add(j,i);for ( i = 1; i <= n; i++ )if ( ! dfn[i] ) Tarjan(i,-1);int res = 0;for ( i = 1; i <= n; i++ )if ( expell[i] ) res++;printf("%d\n", res );}return 0;
}

POJ 2942 Knights of the Round Table (奇圈+点双联通)相关推荐

  1. poj 2942 Knights of the Round Table(双连通分量+tarjan+二分图判定)

    http://poj.org/problem?id=2942 题意: 有N个骑士,给出某些骑士之间的仇恨关系,骑士们开会时会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件: 1:任意相互憎恨的 ...

  2. POJ - 2942 Knights of the Round Table (双连通分量)

    题目链接 题意 有N个骑士,每个骑士有自己不喜欢的人,你需要选择奇数个骑士开一个圆桌会议,每个骑士不能和自己不喜欢的人挨着坐. 问需要删除那些人,这些人不能组成圆桌会议 思路 按照补图建边求双连通分量 ...

  3. POJ - 2942 Knights of the Round Table(点双缩点+二分图判定)

    题目链接:点击查看 题目大意:国王要在圆桌上召开骑士会议,但是有若干对骑士之间互相憎恨.出于各种各样奇怪的原因,每次开会都必须有以下要求: 相互憎恨的两个骑士不能坐在相邻的两个位置 为了让投票表决议题 ...

  4. POJ 2942 Knights of the Round Table ★(点双连通分量+二分图判定)

    题意:找出图中不可能在奇圈中的点. [分析]注意到,在不同点双连通分量中的两个点,显然是不会存在圈的.那么这样,问题就划归为在点双连通分量中去找奇圈. [重要性质]在一个点双连通分量中,只要有任意一个 ...

  5. POJ 2942 Knights of the Round Table 【点双联通 + 二分图染色法判奇环】

    传送门 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1. 相互憎恨的两个骑士不能坐在直接相邻的2个位置: ...

  6. POJ 2942 Knights of the Round Table (算竞进阶习题)

    很巧的一道点双 两个骑士如果相互憎恨,我们考虑连边的话,不太好处理答案,所以我们尝试一下建反图. 如果两个骑士没有相互憎恨,我们就在他们两个人之间连一条无向边,最后要让你会议召开,那么显然是选择任意一 ...

  7. 【POJ - 2942】Knights of the Round Table(点双连通分量,二分图判断奇环奇圈)

    题干: Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in dist ...

  8. UVA1364 Knights of the Round Table(双连通分量、二分图染色,超详细解释)

    整理的算法模板合集: ACM模板 UVA1364 Knights of the Round Table 题目中要求互相有憎恨关系的人不能坐在相邻的位置,一个圆桌可以很形象地看作是一个环,也就是说我们两 ...

  9. 如果圆桌骑士有特殊情况(Knights of the Round Table)

    题目描述 Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in dis ...

最新文章

  1. C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁
  2. uni上传图片跨域_uni-app的项目实践心得
  3. 阿里HBase的数据管道设施实践与演进
  4. Redis 使用 10 个小技巧,请收下!
  5. 第三次学JAVA再学不好就吃翔(part34)--多态的成员访问
  6. Python数据类型与运算符号
  7. Shell脚本基础语法
  8. android java打开wap链接,Android 链接 java 服务无法打开链接的有关问题
  9. SQL 游标使用实例
  10. [C#基础]说说委托+=和-=的那些事
  11. MVC3+EF4.1学习系列(五)----- EF查找导航属性的几种方式
  12. vbs表白代码制作教程
  13. 解决print spooler打印服务自动停止的过程记录
  14. 商城订单实时语音提醒功能JavaScript部分 附提醒语音音频文件
  15. 智慧环保 | 云计算护航环保行业未来可期
  16. 如何优化淘宝直通车推广创意标题
  17. 世界生产力科学院院士(中国籍)名单
  18. 解决IIS+PHP出现的“500 - 内部服务器错误”
  19. ECharts-漏斗图
  20. Clipper:布尔运算类型

热门文章

  1. 对伪装docx文件病毒的逆向分析
  2. charles安装证书并信任证书,仍然无法获取手机上的请求
  3. 【干货】彻底理解Windows认证-议题解读
  4. 日语学习 N1 单词
  5. WordCounter.icu - 一个简单的在线实时字数统计工具
  6. 广州移动华为认证培训之行
  7. aix查看lv_(摘抄)AIX下减小lv size
  8. 【迅为推荐】适合新手学习的arm开发板-iTOP-4412开发板
  9. Celery启动定时任务遇到报错
  10. 利用定时器实现PWM波对Zigbee(CC2530)上LED亮度进行强弱调整