题意:在亚瑟王的圆桌骑士团中,某些骑士两两之间相互憎恨,这样一来他们开会的时候边不能相邻的坐着。即肯定存在某些人不能参加会议。假如一个骑士所有的会议都不能出席,那么他就会被驱逐。现在已知那些骑士之间相互憎恨,求最少要驱逐多少名骑士。(开会时人数必需>=3且为奇数)

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

#include <cstdio>
#include <string.h>
#define maxn 1005
#define maxm 1000005
#define min(a,b) (a<b?a:b);
struct node
{int to;int next;
} edge[maxm];
int map[maxn][maxn];//原图
int head[maxn];//头结点
int Belong[maxn];//i属于第几个双连通分量
int color[maxn];//染色序列
int n, m, cnt, ansi, Index, top, scc; //scc是双连通分量标号
int low[maxn], dfn[maxn], stack[maxn];
int temp[maxn];//临时的栈,存储双连通分支
bool instack[maxn];//是否在栈内
bool expell[maxn];// expell[i]==true表示i需要被驱逐
void init()
{for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if (i != j)map[i][j] = 1;else map[i][j] = 0;for (int i = 1; i <= n; i++){expell[i] = true;instack[i] = false;dfn[i] = low[i] = Belong[i] = 0;head[i] = -1;}Index = cnt = ansi = top = scc = 0;
}
void add(int a, int b)
{edge[ansi].to = b;edge[ansi].next = head[a];head[a] = ansi++;
}
bool odd_cycle(int u, int clr) //判断奇圈
{color[u] = clr;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (Belong[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] = ++Index;for (int i = head[u]; i != -1; i = edge[i].next){v = edge[i].to;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;Belong[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], low[v]);}
}
int main()
{while (scanf("%d%d", &n, &m) != EOF && n + m){init();int a, b;for (int i = 0; i < m; ++i){scanf("%d%d", &a, &b);map[a][b] = map[b][a] = 0;}for (int i = 1; i <= n; ++i){for (int j = 1; j <= n; ++j){if (map[i][j]){add(i, j);add(j, i);}}}for (int i = 1; i <= n; i++){if (!dfn[i])tarjan(i, -1);}int res = 0;for (int i = 1; i <= n; i++)if (expell[i])res++;printf("%d\n", res);}
}

poj2942点双连通奇圈-二分图判断Knights of the Round Table相关推荐

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

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

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

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

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

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

  4. POJ2942 UVA1364 Knights of the Round Table 圆桌骑士

    POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则 ...

  5. POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈

    题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...

  6. POJ 2942 Knights of the Round Table (奇圈+点双联通)

    题意:在亚瑟王的圆桌骑士团中,某些骑士两两之间相互憎恨,这样一来他们开会的时候边不能相邻的坐着.即肯定存在某些人不能参加会议.假如一个骑士所有的会议都不能出席,那么他就会被驱逐.现在已知那些骑士之间相 ...

  7. POJ2942 Knights of the Round Table 点双连通分量 二分图判定

    题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...

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

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

  9. Uvalive 3523 - Knights of the Round Table (双连通分量+二分图)

    题目链接 https://vjudge.net/problem/UVALive-3523 [题意] 有n个骑士经常举行圆桌会议,每次圆桌会议应至少有3个人参加且人数必须是奇数,相互憎恨的骑士不能坐在圆 ...

最新文章

  1. lvs(+keepalived)、haproxy(+heartbeat)、nginx 负载均衡的比较分析
  2. 前阿里巴巴产品专家明卿:当下做通用积分还是个好生意吗?
  3. 笔记本安装linux系统_Win10怎么安装linux双系统?win10安装linux双系统教程
  4. Ui5 tool debug - ctrl alt shift s
  5. 阿里云服务器端口开放对外访问权限
  6. 简述 Spring Cloud 是什么
  7. jzoj6311-Mobitel【dp,整除分块】
  8. VSS Get Latest Version 没有提示recursive的对话框解决
  9. 荣耀V40将采用300Hz 触控采样率,1月18日正式发布!
  10. 0基础学python做什么工作好-零基础学了8个月的Python,到底有啥感悟
  11. Android路由器初始密码,了解路由器用户名和万能密码
  12. VirtualBox成功安装Ubuntu18.04设置共享文件夹总结
  13. 激光SLAM:LOAM-Livox 算法研究(1) -- 功能包编译与验证
  14. Mac系统go版本升级
  15. Go语言系列——31-自定义错误、32-panic和recover、33-函数是一等公民(头等函数)、34-反射、35-读取文件、36-写入文件
  16. 【数字图像处理】Python实现图像变换/沃尔什哈达玛变换(WHT,Walsh-Hadamard Transform)
  17. [转帖]同事推荐的的aira2
  18. 您必须应用的#1规则永远不会在Twitter或Facebook上被骗
  19. java jtable单元格_java表格控件JTable常用操作详解
  20. three.js 制作地球标注的两种方法

热门文章

  1. html控制checkbox选中状态,怎么设置checkbox 选中状态
  2. 用于持续医疗监测的无袖带血压估计算法【翻译】
  3. 【CISSP备考】第七章-安全运营
  4. [学习]简易搜索引擎的制作
  5. VB程序破解常用函数
  6. 机器学习四 数据的差异性
  7. 计算机绘图员证有无取消,计算机辅助设计
  8. C语言程序设计精髓 第2周——数字间的那些事儿,做点计算哈 练兵区——编程题
  9. 中国版权力的游戏构思
  10. 〖Python 数据库开发实战 - MySQL篇㉑〗- 数据表的外连接