[POJ2942][LA3523]Knights of the Round Table
[POJ2942][LA3523]Knights of the Round Table
试题描述
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very surprising that in recent years the kingdom of King Arthur has experienced an unprecedented increase in the number of knights. There are so many knights now, that it is very rare that every Knight of the Round Table can come at the same time to Camelot and sit around the round table; usually only a small group of the knights isthere, while the rest are busy doing heroic deeds around the country.
Knights can easily get over-excited during discussions-especially after a couple of drinks. After some unfortunate accidents, King Arthur asked the famous wizard Merlin to make sure that in the future no fights break out between the knights. After studying the problem carefully, Merlin realized that the fights can only be prevented if the knights are seated according to the following two rules:
The knights should be seated such that two knights who hate each other should not be neighbors at the table. (Merlin has a list that says who hates whom.) The knights are sitting around a roundtable, thus every knight has exactly two neighbors.
An odd number of knights should sit around the table. This ensures that if the knights cannot agree on something, then they can settle the issue by voting. (If the number of knights is even, then itcan happen that
yesandnohave the same number of votes, and the argument goes on.)
Merlin will let the knights sit down only if these two rules are satisfied, otherwise he cancels the meeting. (If only one knight shows up, then the meeting is canceled as well, as one person cannot sit around a table.) Merlin realized that this means that there can be knights who cannot be part of any seating arrangements that respect these rules, and these knights will never be able to sit at the Round Table (one such case is if a knight hates every other knight, but there are many other possible reasons). If a knight cannot sit at the Round Table, then he cannot be a member of the Knights of the Round Table and must be expelled from the order. These knights have to be transferred to a less-prestigious order, such as the Knights of the Square Table, the Knights of the Octagonal Table, or the Knights of the Banana-Shaped Table. To help Merlin, you have to write a program that will determine the number of knights that must be expelled.
\(n\) 个骑士经常参加圆桌会议,一次会议需要选多于一个骑士坐在一张圆桌旁,并且需要满足:
互相憎恨的骑士不能坐在相邻位置;
圆桌旁有奇数个骑士。
问有多少个骑士不能参加任何会议。
输入
The input contains several blocks of test cases. Each case begins with a line containing two integers \(1 \le n \le 1000\) and \(1 \le m \le 1000000\) . The number n is the number of knights. The next \(m\) lines describe which knight hates which knight. Each of these m lines contains two integers \(k_1\) and \(k_2\) , which means that knight number \(k_1\) and knight number \(k_2\) hate each other (the numbers \(k_1\) and \(k_2\) are between \(1\) and \(n\) ).
The input is terminated by a block with n = m = 0 .
输出
For each test case you have to output a single integer on a separate line: the number of knights that have to be expelled.
输入示例
5 5
1 4
1 5
2 5
3 4
4 5
0 0
输出示例
2
数据规模及约定
见“输入”
题解
注意这题是点-双连通分量。(判断是边双还是点双,画几个“8 字形”就好了)
我们将所有的点双依次处理(割点一定要被处理多次,它属于多个点双),看每个点双是否能被二分图染色,不能被二分染色的点双中所有点是可以参加圆桌会议的。
我们可以证明如果一个点双中含有一个简单奇环,那么该双连通分量中所有点都可以在某个简单奇环中。读者不妨自己画一个有交(指边同时在两个环中)奇环和偶环,发现偶环上所有点都可以将它所在偶环的那一半和奇环的一半拼出一个大奇环。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <vector>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i++)
#define dwn(i, s, t) for(int i = (s); i >= (t); i--)
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
}
#define maxn 1010
#define maxm 2000010
struct Edge {
int a, b;
Edge() {}
Edge(int _, int __): a(_), b(__) {}
} es[maxm];
int n, m, head[maxn], nxt[maxm];
bool G[maxn][maxn];
void AddEdge(int a, int b) {
es[++m] = Edge(a, b); nxt[m] = head[a]; head[a] = m;
swap(a, b);
es[++m] = Edge(a, b); nxt[m] = head[a]; head[a] = m;
return ;
}
int clo, dfn[maxn], low[maxn], bcno[maxn], cntb, top;
Edge S[maxm];
vector <int> bcc[maxn];
bool iscut[maxn];
void dfs(int u, int fa) {
dfn[u] = low[u] = ++clo;
int ch = 0;
for(int i = head[u]; i; i = nxt[i]) if(i != fa) {
Edge& e = es[i];
if(dfn[e.b]) low[u] = min(low[u], dfn[e.b]);
else {
S[++top] = e;
dfs(e.b, i); ch++;
low[u] = min(low[u], low[e.b]);
if(low[e.b] >= dfn[u]) {
iscut[u] = 1;
cntb++;
while(1) {
Edge s = S[top--];
if(bcno[s.a] != cntb) bcno[s.a] = cntb, bcc[cntb].push_back(s.a);
if(bcno[s.b] != cntb) bcno[s.b] = cntb, bcc[cntb].push_back(s.b);
if(s.a == e.a && s.b == e.b) break;
}
}
}
}
if(!fa && ch == 1) iscut[u] = 0;
return ;
}
bool cant[maxn];
int col[maxn];
bool solve(int u, int b, int c) {
if(col[u]) return col[u] == c;
col[u] = c;
for(int i = head[u]; i; i = nxt[i]) {
Edge& e = es[i];
if(bcno[e.b] == bcno[u] && !solve(e.b, b, 3 - c)) return 0;
}
return 1;
}
int main() {
while(1) {
n = read(); int M = read();
if(!n) break;
memset(G, 0, sizeof(G));
rep(i, 1, M) {
int a = read(), b = read();
G[a][b] = G[b][a] = 1;
}
m = 0; memset(head, 0, sizeof(head));
rep(i, 1, n)
rep(j, i + 1, n) if(!G[i][j]) AddEdge(i, j);
memset(dfn, 0, sizeof(dfn)); clo = 0;
memset(low, 0, sizeof(low));
memset(bcno, 0, sizeof(bcno));
rep(i, 1, cntb) bcc[i].clear();
cntb = 0;
rep(i, 1, n) if(!dfn[i]) dfs(i, 0);
/*printf("cntb: %d\n", cntb);
rep(i, 1, cntb) {
printf("%d:", i);
for(vector <int> :: iterator j = bcc[i].begin(); j != bcc[i].end(); j++)
printf(" %d", *j);
putchar('\n');
}*/
memset(cant, 0, sizeof(cant));
rep(i, 1, cntb) {
for(vector <int> :: iterator j = bcc[i].begin(); j != bcc[i].end(); j++)
bcno[*j] = i;
memset(col, 0, sizeof(col));
if(!solve(*bcc[i].begin(), i, 1))
for(vector <int> :: iterator j = bcc[i].begin(); j != bcc[i].end(); j++)
cant[*j] = 1;
}
int cnt = n;
rep(i, 1, n) cnt -= cant[i];
printf("%d\n", cnt);
}
return 0;
}
[POJ2942][LA3523]Knights of the Round Table的更多相关文章
- POJ2942 UVA1364 Knights of the Round Table 圆桌骑士
POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则 ...
- 【poj2942】 Knights of the Round Table
http://poj.org/problem?id=2942 (题目链接) 题意 有n个骑士要去参加圆桌会议,他们将围成一圈,想要他们不打架,当且仅当参加圆桌会议的骑士数为奇数并且相邻的两个骑士不互相 ...
- POJ2942:Knights of the Round Table——题解
http://poj.org/problem?id=2942 所写的tarjan练习题最难的一道. 说白了难在考得不是纯tarjan. 首先我们把仇恨关系处理成非仇恨关系的图,然后找双连通分量,在双连 ...
- 【POJ2942】Knights of the Round Table(二分图 点双联通分量)
题目链接 大意 给定\(N\)个点与\(M\)个关系,每个关系表示某两个点间没有直接的边相连,求不在所有奇环上的点的个数. (\(1\le N\le 1e3,1\le M\le 1e6\)) 思路 考 ...
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
- 「题解」:[POJ2942]Knights of the Round Table
问题 E: Knights of the Round Table 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 作为一名骑士是一个非常有吸引力的职业:寻找圣杯,拯救遇难的少女,与 ...
- POJ 2942 Knights of the Round Table
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 10911 Acce ...
- poj 2942 Knights of the Round Table 圆桌骑士(双连通分量模板题)
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 9169 Accep ...
随机推荐
- 运维如何延续自己的职业生涯--萧田国2017年GOPS深圳站演讲内容
正如 萧田国在2017年GOPS深圳站演讲所提及的,运维职业生涯规划,应该是T字型. 关于指导原则,正如腾讯好友@赵建春所言: 如果一个领域不能做到TOP,那就是一种伤害. 运维在编程.开发领域,能做 ...
- 手机上如何远程控制Linux服务器?
这里介绍3个手机软件,分别是JuiceSSH.Termius和Termux,这3个软件都可以实现远程控制Linux服务器(相当于手机SSH客户端),而且使用起来都非常方便,下面我简单介绍一下这3个软件 ...
- python_77_json与pickle序列化3
#此方法:dump多次,而不可以load多次,只能load一次,否则会出错 只有序列化,无反序列化 import json info={ 'name':'Xue Jingjie', 'age':22, ...
- ambari过程中要求各个节点时间同步
设置时间同步 控制节点机器 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #设置时区为北京时间,这里为上海,因为centos里面只有上海... ...
- GIT 团队协作快速入门使用
GIT使用: 1.本地新建一个文件夹 git init 2.克隆远程仓库 git clone git@xxxxx.git 3.本地创建一个dev分支 (前提是服务器端已经创建好有 DEV 分支) gi ...
- >详解< 广度优先搜索
>概念< 广度优先搜索 概念 (其实我也不是很明白)广度优先搜索(简称广搜)(别名宽度优先搜索).采用了树形结构.常用于寻找 最短路线问题. -The end- 2018.7.12
- ajaxfileuplod 上传文件 essyui laoding 效果,防止重复上传文件
//放于上传前 function ajaxLoading(){ $("<div class=\"datagrid-mask\"></div>&qu ...
- mysql查询哪个表数据量最大
use information_schema;select table_name,table_rows from tables where table_schema='cargo_new' order ...
- Keywords Search HDU - 2222 ( ac自动机)模版题
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- 5、python中的列表
list是python内置的一种有序.可变的数据结构. 一.如何创建一个list? 示例: 注意: list中的元素可以是任意的数据类型如字符串.数字.布尔值.None等,也可以是其他的数据结构如另外 ...