【POJ】2942 Knights of the Round Table(双连通分量)
http://poj.org/problem?id=2942
各种逗。。。。
翻译白书上有;看了白书和网上的标程,学习了。。orz。
双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果这个是割点那么子树就都是双连通分量,然后本题求的是奇圈,那么就进行黑白染色,判断是否为奇圈即可。将不是奇圈的所有双连通分量的点累计起来即可。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; } const int N=1005, M=1000005;
int ihead[N], n, m, cnt, LL[N], FF[N], mp[N][N], tot, s[M<<1], top, vis[N], ok[N], col[N];
struct ED { int from, to, next; } e[M<<1];
void add(int u, int v) {
e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].from=u;
e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].to=u; e[cnt].from=v;
}
bool ifind(int u) {
int v;
for(int i=ihead[u]; i; i=e[i].next) if(vis[v=e[i].to]) {
if(col[v]==-1) { col[v]=!col[u]; return ifind(v); }
else if(col[v]==col[u]) return true;
}
return false;
}
void color(int x) {
int y, u=e[x].from;
CC(vis, 0); CC(col, -1); col[u]=0;
do {
y=s[top--];
vis[e[y].from]=vis[e[y].to]=1;
} while(y!=x);
if(ifind(u)) for1(i, 1, n) if(vis[i]) ok[i]=1;
}
void tarjan(int u, int fa) {
FF[u]=LL[u]=++tot;
for(int i=ihead[u]; i; i=e[i].next) if(fa!=e[i].to) {
int v=e[i].to;
if(!FF[v]) {
s[++top]=i; //入栈这里要注意。。不要在上边入栈。。
tarjan(v, u);
if(LL[v]>=FF[u]) color(i);
LL[u]=min(LL[u], LL[v]);
}
else if(LL[u]>FF[v]) s[++top]=i, LL[u]=FF[v]; //入栈这里要注意。。
}
}
int main() {
while(1) {
read(n); read(m); int ans=0;
if(n==0 && m==0) break;
CC(mp, 0); CC(ihead, 0); CC(LL, 0); CC(FF, 0); CC(ok, 0); top=cnt=tot=0;
rep(i, m) {
int u=getint(), v=getint();
mp[u][v]=mp[v][u]=1;
}
for1(i, 1, n) for1(j, i+1, n) if(!mp[i][j]) add(i, j);
for1(i, 1, n) if(!FF[i]) tarjan(i, -1);
for1(i, 1, n) if(!ok[i]) ++ans;
printf("%d\n", ans);
}
return 0;
}
Description
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 ``yes" and ``no" have 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.
Input
input contains several blocks of test cases. Each case begins with a
line containing two integers 1 ≤ n ≤ 1000 and 1 ≤ m ≤ 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
k1 and k2 , which means that knight number k1 and knight number k2 hate
each other (the numbers k1 and k2 are between 1 and n ).
The input is terminated by a block with n = m = 0 .
Output
Sample Input
5 5
1 4
1 5
2 5
3 4
4 5
0 0
Sample Output
2
Hint
Source
【POJ】2942 Knights of the Round Table(双连通分量)的更多相关文章
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
		
题目来源:POJ 2942 Knights of the Round Table 题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条 ...
 - poj 2942 Knights of the Round Table  圆桌骑士(双连通分量模板题)
		
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 9169 Accep ...
 - poj 2942 Knights of the Round Table - Tarjan
		
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
 - 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 - from lanshui_Yang
		
Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels ...
 - poj 2942 Knights of the Round Table(点双连通分量+二分图判定)
		
题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...
 - POJ 2942 Knights of the Round Table (点双连通分量)
		
题意:多个骑士要开会,3人及以上才能凑一桌,其中部分人已经互相讨厌,肯定不坐在同一桌的相邻位置,而且一桌只能奇数个人才能开台.给出多个人的互相讨厌图,要求多少人开不成会(注:会议不要求同时进行,一个人 ...
 - POJ 2942.Knights of the Round Table (双连通)
		
简要题解: 意在判断哪些点在一个图的 奇环的双连通分量内. tarjan求出所有的点双连通分量,再用二分图染色判断每个双连通分量是否形成了奇环,记录哪些点出现在内奇环内 输出没有在奇环内的点的数目 ...
 - POJ - 2942 Knights of the Round Table (点双联通分量+二分图判定)
		
题意:有N个人要参加会议,围圈而坐,需要举手表决,所以每次会议都必须是奇数个人参加.有M对人互相讨厌,他们的座位不能相邻.问有多少人任意一场会议都不能出席. 分析:给出的M条关系是讨厌,将每个人视作点 ...
 - poj 2942 Knights of the Round Table(无向图的双连通分量+二分图判定)
		
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #includ ...
 
随机推荐
- Office 如何双面打印Word文档
			
打印之前勾选手动双面打印,然后开始打印(不管当前文档有几页,要打印几份,会只打印奇数页面) 只要开始打印奇数页面,就会有一个弹出窗口,当完成之后把打印的东西拿出来,整个翻面再放回打印机,点击确定会 ...
 - PHP安全:如何正确的取得使用者 IP?
			
PHP安全:如何正确的取得使用者 IP? 很多网站都会有侦测用户 IP 的功能,不管是判断使用者来自哪边,或者是记录用户的位置.但是你知道吗?网络上大多数的教学全部都是「错误」的.正确的程序写法可以确 ...
 - js设置加载进度提示
			
CreateTime--2017年8月23日09:17:46Author:Marydon js设置加载进度提示 第一部分:CSS /*加载样式*/ .Loading { position: abs ...
 - 【DB2】DbVisualizer编译存储过程
			
之前我一直以为DbVisualizer是不可以编译存储过程的,现在才发现是可以的,编译如下: 只需要在编译的时候注意使用--/与/将存储过程包为起来编辑即可.
 - js 获取select的值 / js动态给select赋值
			
jQuery获取Select选择的Text和Value:语法解释:1. $("#select_id").change(function(){//code...}); //为Se ...
 - Shell 脚本修改 Mac IP地址
			
本篇文章由:http://xinpure.com/shell-script-to-modify-the-mac-ip-address/ 麻烦事 最近在笔记本 WIFI 网络上遇到一个麻烦事, 在公司需 ...
 - javascript解析器(引擎)
			
The JavaScript interpreter in a browser is implemented as a single thread. javascript 引擎在浏览器中作为单线程实现 ...
 - Josephus排列
			
思考与分析: 对于m为常数,能够用循环链表,用head,tail标志头尾指针使其易于表示循环结构.循环输出后删除结点n次,每次外层循环时.内层都固定循环m次.所以执行时间为O(mn)=O(n). 对于 ...
 - js 获取距离顶部的相对高度
			
getTop (e) { var offset=e.offsetTop; if(e.offsetParent!=null) offset+=this.getTop(e.offsetParent); r ...
 - Sublime Text快捷键去除空白行 - 转载请保留原文链接:https://www.noniu.com/qianduan/sublime-text-kongbaihang.html
			
如果使用notepad++或者Dreamweaver的朋友,应该知道有个快捷键或者功能按钮,可以实现删除文档空白行的功能.虽然空白行不会影响程序运行,但是会占一定的空间,对于有处女座特质的程序员来说, ...