UVA 1364 - Knights of the Round Table (获得双连接组件 + 二部图推理染色)
尤其是不要谈了些什么,我想A这个问题!
FML啊.....!
题意来自 kuangbin:
亚瑟王要在圆桌上召开骑士会议。为了不引发骑士之间的冲突。 而且可以让会议的议题有令人惬意的结果,每次开会前都必须对出席会议的骑士有例如以下要求: 1、 相互憎恨的两个骑士不能坐在直接相邻的2个位置; 2、 出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果。
注意:1、所给出的憎恨关系一定是双向的。不存在单向憎恨关系。 2、因为是圆桌会议。则每一个出席的骑士身边必然刚好有2个骑士。
即每一个骑士的座位两边都必然各有一个骑士。 3、一个骑士无法开会,就是说至少有3个骑士才可能开会。
首先依据给出的互相憎恨的图中得到补图。 然后就相当于找出不能形成奇圈的点。 利用以下两个定理: (1)假设一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈)。 那么这个双连通分量的其它顶点也在某个奇圈中; (2)假设一个双连通分量含有奇圈,则他必然不是一个二分图。反过来也成立。这是一个充要条件。
所以本题的做法,就是对补图求点双连通分量。 然后对于求得的点双连通分量,使用染色法推断是不是二分图,不是二分图。这个双连通分量的点是能够 存在的 */
这样,思路例如以下:
1.找出全部的双连通分量;
2.推断找出的双联通分量似不似一个二分图,假设是二分图,说明它不含有奇圈,不符合题意,反之符合题意,所以在该连通分量中的点都是能够上桌开会的点...
详细思路就是这个样子了~然后照着刘汝佳大白书上的 找双联通分量 的算法,以及 染色法判二分图 的方法,就ok了
没有办法。太水了我仅仅能理解到这里才干做题了尼玛啊 !
!
T_T.....
没有大神讲,变量的意思想了一上午卧槽好傻逼。
。。
接下来会有一篇给一些变量凝视的!
大白书上的代码。造福弱逼不用谢。
#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
using namespace std; const int N = 1005; struct Edge {
int u, v;
Edge() {}
Edge(int u, int v) {
this->u = u;
this->v = v;
}
};
///bccno[]是用来表示 编号为i的点在哪一个双连通分量中! ///bcc_cnt是用来表示 总共同拥有几个双连通分量
int pre[N], bccno[N], dfs_clock, bcc_cnt;
bool iscut[N]; vector<int> g[N], bcc[N];///用来存下来每个双连通分量
stack<Edge> S; int dfs_bcc(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]) {
S.push(e);
child++;
int lowv = dfs_bcc(v, u);
lowu = min(lowu, lowv);
if (lowv >= pre[u]) {
iscut[u] = true;
bcc_cnt++; bcc[bcc_cnt].clear(); //start from 1
while(1) {
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] = false;
return lowu;
} void find_bcc(int n) {
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_bcc(i, -1);
} int odd[N], color[N]; 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 n, m, A[N][N]; int main() {
int cas = 0;
while (~scanf("%d%d", &n, &m) && 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++)
ans -= odd[i];
printf("%d\n", ans);
}
return 0;
}
版权声明:请注明出处撒...http://blog.csdn.net/u013382399
UVA 1364 - Knights of the Round Table (获得双连接组件 + 二部图推理染色)的更多相关文章
- 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)
[POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS Memory Limit: 65536K Total Su ...
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- 【POJ】2942 Knights of the Round Table(双连通分量)
http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...
- uva 3523 Knights of the Round Table
题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议. 白书算法指南 对于每个双联通分量,若不是二分图,就把里面的节点标记 #include ...
- POJ 2942 Knights of the Round Table(双连通分量)
http://poj.org/problem?id=2942 题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果意见发生分歧,则需要举手表决,因此 ...
- POJ 2942.Knights of the Round Table (双连通)
简要题解: 意在判断哪些点在一个图的 奇环的双连通分量内. tarjan求出所有的点双连通分量,再用二分图染色判断每个双连通分量是否形成了奇环,记录哪些点出现在内奇环内 输出没有在奇环内的点的数目 ...
- POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈
题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...
- poj 2942 Knights of the Round Table(点双连通分量+二分图判定)
题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...
- UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)
题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向 ...
随机推荐
- hdu 4107当卡段树
其核心思想是记录最大的节点值和最低值,假设max<p要么min>=p时间,在节点只变化add值,不要子树遍历:否则,就往子树递归. #include<iostream> #in ...
- C++ Primer 学习笔记_57_类和数据抽象 --管理指针成员
复印控制 --管理指针成员 引言: 包括指针的类须要特别注意复制控制.原因是复制指针时.一个带指针成员的指针类 class HasPtr { public: HasPtr(int *p,int i): ...
- android CountDownTimer
最近进行的项目使用的定时功能,我发现了一个非常容易使用内置类CountDownTimer.当然,可以使用这种效果TimerTask + Timer为了实现.只是我个人的意见CountDownTimer ...
- 基础知识(2)- Java程序设计环境
2.1 安装Java开发工具箱 2.1.1 下载JDK 2.1.2 设置执行路径 2.1.3 安装库源文件和文档 2.1.4 安装本书中的示例 2.1.5 导航Java目录 2.2 选择开发 ...
- lock订单号
常见误用场景:在订单支付环节中,为了防止用户不小心多次点击支付按钮而导致的订单重复支付问题,我们用 lock(订单号) 来保证对该订单的操作同时只允许一个线程执行. 这样的想法很好,至少比 lock( ...
- Zoj 3545 Rescue the Rabbit(ac自己主动机+dp)
标题效果: 鉴于DNA有一个正确的顺序值.请构造一个长度I的DNA在这个序列使DNA正确的顺序值极大.它被认为是负的输出噼啪. .. IDEAS: 施工顺序是,ac己主动机上走,求最大要用到dp dp ...
- "Cannot find entry symbol nable-stdcll-fixup; defaulting to 00401000" 解决方案
在使用Qt 4.7.3, Qt 4.7.2 ,Qt 4.7.1(mingw 4.6.2 )的时候都会有一个问题无法编译通过,即用Qt Creator 编译的时候会发生一个错误 "Cannot ...
- sql function递归
alter function Fn_GetUserGroupRelation ( @DHsItemID int ) returns nvarchar(1024) begin declare @Col_ ...
- java提高篇(三)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- 【Android进阶】使用第三方平台ShareSDK实现新浪微博的一键分享功能
在公司最近的一个项目中,需要实现一键分享功能,在这里我使用的是第三方平台ShareSDK,将使用经验与大家分享 先看效果图 主界面 分享界面 由于第一次使用,所以需要先进行新浪授权,授权界面 分享结果 ...