题目:http://poj.org/problem?id=2942
题意:

一群骑士,某些骑士之间互相憎恨,如果在一起容易发生争斗事件,因此他们只有满足一定条件才能参加圆桌会议:1.圆桌边上任意相邻的两个骑士不能互相憎恨;2。同一个圆桌边上的骑士数量必须是奇数;

分析:

这题训练指南上有详解,分析是copy自JosiahChiu的,书上写的挺详细的。我主要是贴一下作为模板~~
1 骑士ij连边(无向边),表示这两个骑士没有憎恨关系(可以坐在一起)。
2 这样建图后,实质是问每个骑士能否在一个奇环内即可。
3 然后按照点双连通分块,容易知道,如果i骑士能分在一个奇环内,这个环一在i骑士所在的块内。
4 此时问题转化为:在块内找奇环。
5 有一条很好的性质:如果这个块内,只要存在一个奇环(不管这个环有多少的点),那么这个块的所有点都可以被奇环包围。
6 那么奇环很好判断:二分图染色后,只要有一个点和它的相邻节点的颜色相同,就找到了奇环。

代码:

// LA3523 Knights of the Round Table
// Rujia Liu
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>using namespace std;struct Edge {int u, v;
};const int maxn = 1000 + 10;
int pre[maxn], iscut[maxn], bccno[maxn], dfs_clock, bcc_cnt; // 割顶的bccno无意义
vector<int> G[maxn], bcc[maxn];stack<Edge> S;int dfs(int u, int fa) {int lowu = pre[u] = ++dfs_clock;int child = 0;for(int i = 0; i < G[u].size(); i++) {int v = G[u][i];Edge e = (Edge) {u, v};if(!pre[v]) { // 没有访问过vS.push(e);child++;int lowv = dfs(v, u);lowu = min(lowu, lowv); // 用后代的low函数更新自己if(lowv >= pre[u]) {iscut[u] = true;bcc_cnt++;bcc[bcc_cnt].clear();for(;;) {Edge x = S.top();S.pop();if(bccno[x.u] != bcc_cnt) {bcc[bcc_cnt].push_back(x.u);bccno[x.u] = bcc_cnt;}if(bccno[x.v] != bcc_cnt) {bcc[bcc_cnt].push_back(x.v);bccno[x.v] = bcc_cnt;}if(x.u == u && x.v == v) break;}}} else if(pre[v] < pre[u] && v != fa) {S.push(e);lowu = min(lowu, pre[v]); // 用反向边更新自己}}if(fa < 0 && child == 1) iscut[u] = 0;return lowu;
}void find_bcc(int n) {// 调用结束后S保证为空,所以不用清空memset(pre, 0, sizeof(pre));memset(iscut, 0, sizeof(iscut));memset(bccno, 0, sizeof(bccno));dfs_clock = bcc_cnt = 0;for(int i = 0; i < n; i++)if(!pre[i]) dfs(i, -1);
}int odd[maxn], color[maxn];
bool bipartite(int u, int b) {for(int i = 0; i < G[u].size(); i++) {int v = G[u][i];if(bccno[v] != b) continue;if(color[v] == color[u]) return false;if(!color[v]) {color[v] = 3 - color[u];if(!bipartite(v, b)) return false;}}return true;
}int A[maxn][maxn];int main() {int kase = 0, n, m;while(scanf("%d%d", &n, &m) == 2 && n) {for(int i = 0; i < n; i++) G[i].clear();memset(A, 0, sizeof(A));for(int i = 0; i < m; i++) {int u, v;scanf("%d%d", &u, &v);u--;v--;A[u][v] = A[v][u] = 1;}for(int u = 0; u < n; u++)for(int v = u+1; v < n; v++)if(!A[u][v]) {G[u].push_back(v);G[v].push_back(u);}find_bcc(n);memset(odd, 0, sizeof(odd));for(int i = 1; i <= bcc_cnt; i++) {memset(color, 0, sizeof(color));for(int j = 0; j < bcc[i].size(); j++) bccno[bcc[i][j]] = i; // 主要是处理割顶int u = bcc[i][0];color[u] = 1;if(!bipartite(u, i))for(int j = 0; j < bcc[i].size(); j++) odd[bcc[i][j]] = 1;}int ans = n;for(int i = 0; i < n; i++) if(odd[i]) ans--;printf("%d\n", ans);}return 0;
}

poj 2942-圆桌骑士(点双连通分量+二分图)相关推荐

  1. POJ 2942 圆桌骑士 (点双学习笔记)

    割点 在无向连通图G上进行如下定义: • 割点:若删掉某点P后,G分裂为两个或两个以上的子图,则称P为G的割点. • 割点集合:在无向连通图G中,如果有一个顶点集合,删除这个顶点集合以及与该点集中 的 ...

  2. POJ 2942 圆桌骑士

    之前做过这个题目,现在回想起来,又有新的柑橘. 求必须出去的骑士人数. 每一个双连通分量,如果是一个奇圈,那么一定是二分图染色失败. 依次遍历每个双连通分量,但是,对于邻接表中,有一些点不是双连通分量 ...

  3. 【LA3523 训练指南】圆桌骑士 【双连通分量】

    题意 有n个骑士经常举行圆桌会议,商讨大事.每次圆桌会议至少应有3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防赞同和反 ...

  4. poj 2942 圆桌骑士 无向图割点 奇圈 交叉染色

    连通类经典题 题意及分析参考: 1.建反向图 2.tarjan 算法求割点3.二部图与奇圈 4.交叉染色 http://blog.csdn.net/lyy289065406/article/detai ...

  5. poj2942 圆桌骑士(点双连通分量+二分图染色法判奇环)

    题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 分析:图论 ...

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

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

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

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

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

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

  9. poj 3352 Road Construction(边-双连通分量)

    题意:给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图. 解题思路: 显然,当图G存在桥(割边)的时候,它必定不是双连通的.桥的两个端点必定分别属于图G的两个[边双连通分量](注意不是点 ...

  10. Redundant Paths POJ - 3177(tarjan+边双连通分量)

    题意: 有n个牧场,要求从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路.两条独立的路是指:没有公共边的路,但可以经过 ...

最新文章

  1. 靠纯技术是否能渡过中年危机
  2. 对话框属性页(VC_MFC)
  3. 用openCV去除文字中乱入的线条
  4. HDFS namenode 高可用(HA)搭建指南 QJM方式 ——本质是多个namenode选举master,用paxos实现一致性...
  5. 学好计算机科学的诀窍,【教学方法论文】计算机科学技术专业高效教学方法(共4295字)...
  6. python post请求_python发送http的post请求
  7. JVM学习笔记之-执行引擎(Execution Engine)
  8. [Leedcode][JAVA][第146题][LRU][哈希表][双向链表]
  9. 35 CO配置-控制-产品成本控制-成本对象控制-期末结算-定义在产品和废品的评估变式 (目标成本)
  10. PyCharm平台下初学Django框架
  11. oracle 回表是什么,ORACLE回表
  12. IEEE MAC地址分配
  13. Git创建版本库及git init 、add 和 commit -m 的基本使用
  14. [iOS]手把手教你实现微信小视频
  15. 【Data truncation: Data too long for column ‘XXX at row 1 报错】
  16. LaTeX--1--了解LaTeX
  17. 上电瞬间电容相当于短路
  18. 【中塘镇】助力儿童,健康成长---创意超轻黏土手工制作主题活动
  19. 流动性持续改善,佳源国际迎来“戴维斯双击”?
  20. Python中各种进制之间的转换

热门文章

  1. js随机生成4位验证码(包括数字英文大小写)
  2. 如何限制上传附件的格式?
  3. pageoffice在vue+springboot前后端分离项目中的应用方法
  4. ubuntu 通过命令行上传百度云
  5. 一级计算机考证多少分过
  6. 人穷志不短,穷学生也能玩转树莓派
  7. 基于JavaWeb的鲜牛奶订购系统的设计与实现
  8. 汽车分析,随时间变化的燃油效率
  9. 鼠标点击特效——富强、民主、文明、和谐.....
  10. 最新版某白酒app MT-V定位及带壳frida-hook实战