POJ - 2942 Knights of the Round Table (点双联通分量+二分图判定)
题意:有N个人要参加会议,围圈而坐,需要举手表决,所以每次会议都必须是奇数个人参加。有M对人互相讨厌,他们的座位不能相邻。问有多少人任意一场会议都不能出席。
分析:给出的M条关系是讨厌,将每个人视作点,在没有讨厌关系的人之间连边。
问题中很重要的一点是:任意一场会议都不能参加。能够参加某一场会议就意味着,参加会议的人可以构成一个奇回路(他们要围圈而坐,且必须出席奇数个人)。那么问题就转化成了求有多少个点不在任意一个奇回路中。
简单圈上的所有结点都属于同一个点双连通分量,因此找出所有的点双连通分量,并对该点双连通分量中判断其是否为二分图(二分图不含奇圈)。如果不是二分图,则表示其含有奇圈。打上标记,最后用点数N-没有被打上标记的点数,就是答案。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stack>
using namespace std;
const int maxn =1e3+;
const int maxm = 1e6+;
struct Edge{
int to,next;
}edges[maxm<<];
bool instack[maxn];
int bccno[maxn],head[maxn],dfn[maxn],low[maxn],clk,top,scc;
stack<int> S;
int col[maxn];
int ans;
bool check[maxn];
int tag[maxn];
bool can[maxn]; bool dfs(int u,int c)
{
col[u]=c;
for(int i=head[u]; i!=-; i=edges[i].next){
int v=edges[i].to;
if(!check[v])
continue;
if(col[v]!=-){
if(col[v]==c)
return false;
continue;
}
if(!dfs(v,!c))
return false;
}
return true;
}
void init()
{
clk = top = scc = ;
memset(head,-,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(bccno,,sizeof(bccno));
memset(instack,,sizeof(instack));
memset(can,,sizeof(can));
} void AddEdge(int u,int v)
{
edges[top].to = v;
edges[top].next =head[u];
head[u] = top++;
} void Tarjan(int u,int id)
{
int v;
low[u]=dfn[u]=++clk;
S.push(u);
instack[u]=true;
for(int i=head[u];~i;i=edges[i].next){
v = edges[i].to;
if(i==(id^)) continue;
if(!dfn[v]){
Tarjan(v,i);
low[u]=min(low[u],low[v]);
if(dfn[u]<=low[v]){ //找到一个双连通分量
scc++; //从1开始
int cnt=;
memset(check,,sizeof(check)); //判断是否在同一个双连通分量内
while(true){
int x =S.top();S.pop();
tag[cnt++] = x;
bccno[x]=scc; //确定分量编号
instack[x]=false;
check[x] =true;
if(x==v) break; //找到了自己就要停止标号
}
check[u] = true;
memset(col,-,sizeof(col)); //判断双连通分量内是否有奇圈
if(!dfs(u,)){
can[u] = true;
while(cnt--) can[tag[cnt]] = true;
}
}
}
else if(instack[v])
low[u]= min(low[u],dfn[v]);
} } int G[maxn][maxn]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T,N,M,u,v,tmp;
while(scanf("%d%d",&N,&M)==){
if(!N) break;
init();
memset(G,,sizeof(G));
for(int i=;i<=M;++i){
scanf("%d%d",&u,&v);
G[u][v] = G[v][u] = ;
}
for(int i=;i<=N;++i){
for(int j=i+;j<=N;++j){
if(!G[i][j]){
AddEdge(i,j);
AddEdge(j,i);
}
}
}
for(int i=;i<=N;++i){
if(!dfn[i])
Tarjan(i,-);
}
ans= N;
for(int i=;i<=N;++i){
if(can[i]) ans--;
}
printf("%d\n",ans);
}
return ;
}
POJ - 2942 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 ...
- POJ 2942 Knights of the Round Table(双连通分量)
http://poj.org/problem?id=2942 题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果意见发生分歧,则需要举手表决,因此 ...
- poj 2942 Knights of the Round Table(点双连通分量+二分图判定)
题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...
- POJ 2942.Knights of the Round Table (双连通)
简要题解: 意在判断哪些点在一个图的 奇环的双连通分量内. tarjan求出所有的点双连通分量,再用二分图染色判断每个双连通分量是否形成了奇环,记录哪些点出现在内奇环内 输出没有在奇环内的点的数目 ...
- 【洛谷 SP2878】Knights of the Round Table(双联通分量)
先放这吧,没时间写,明天再补 "明天到了" 题目链接 题意:求不在任何奇环内的点的数量. Tarjan求点双联通分量,然后再染色判断是不是二分图就好了. 只是不懂为什么Tarjan ...
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
题目来源:POJ 2942 Knights of the Round Table 题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条 ...
- 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(双连通分量)
http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...
- POJ 2942 Knights of the Round Table
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 10911 Acce ...
随机推荐
- 移动端上下滑动事件之--坑爹的touch.js
原文 http://blog.csdn.net/minidrupal/article/details/39611605 移动端页面的盛行,微信的便利的页面推广等等,让越来越多的css3效果和htm ...
- 网页端的utf8和gb2312 之间关于osd 传参数的乱码问题
(0)HZK16 点阵字库原理及实现 (1)utf8 和 unicode gb2312之间的转换 (2)gb2312 的拓展 gbk 实现了更多的文字编码 像“瞭望塔”的瞭子在gb2312中是没有的 ...
- 嵌入式驱动开发之phy---fine Mac与Phy组成原理的简单分析
关键字rj45.pci-e 1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器通常属于CPU的一部分,用虚线放在这里是为了表示DMA控制器可能会参与到网口数 ...
- git 入门一(初识)
分布式版本控制系统 & 集中式版本控制系统 分布式版本控制系统( Distributed Version Control System)在这类系统中,像 Git,Mercurial,Baz ...
- php视频教程
网址:http://www.php100.com/index.html
- JDK动态代理具体解释
首先说一下动态代理和静态代理的差别: 静态代理:是预先写好或由特定工具自己主动生成的代码.再对其编译.在程序执行前.代理类的.class文件就已经存在了. 动态代理:代理是在程序执行时,运用反射机制动 ...
- HibernateSessionFactory演示样例
package common; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hi ...
- Java接口成员变量和方法默认修饰符
Java的interface中,成员变量的默认修饰符为:public static final 所以我们在interface中定义成员变量的时候,可以 1:public static final S ...
- [原创]Nexus5 移植OneStep
OneStep 简介 https://github.com/SmartisanTech/android One Step 涉及的工程列表: frameworks_base (需要更改WindowMan ...
- python 之 GIL(线程和进程的应用)
一.GIL:http://www.tuicool.com/articles/7zIra2r http://www.zhihu.com/question/23474039 二.线程锁 在threadi ...