题意:有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 (点双联通分量+二分图判定)的更多相关文章

  1. 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

    [POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Su ...

  2. POJ 2942 Knights of the Round Table(双连通分量)

    http://poj.org/problem?id=2942 题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果意见发生分歧,则需要举手表决,因此 ...

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

    题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...

  4. POJ 2942.Knights of the Round Table (双连通)

    简要题解: 意在判断哪些点在一个图的  奇环的双连通分量内. tarjan求出所有的点双连通分量,再用二分图染色判断每个双连通分量是否形成了奇环,记录哪些点出现在内奇环内 输出没有在奇环内的点的数目 ...

  5. 【洛谷 SP2878】Knights of the Round Table(双联通分量)

    先放这吧,没时间写,明天再补 "明天到了" 题目链接 题意:求不在任何奇环内的点的数量. Tarjan求点双联通分量,然后再染色判断是不是二分图就好了. 只是不懂为什么Tarjan ...

  6. POJ 2942 Knights of the Round Table 黑白着色+点双连通分量

    题目来源:POJ 2942 Knights of the Round Table 题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条 ...

  7. 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 ...

  8. 【POJ】2942 Knights of the Round Table(双连通分量)

    http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...

  9. POJ 2942 Knights of the Round Table

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 10911   Acce ...

随机推荐

  1. Bootstrap Multiselect 设置 option

    $.ajax({ type: 'post', url: "helper/ajax_search.php", data: {models: decodeURIComponent(br ...

  2. 马尔科夫毯(Markov Blanket)

    最优特征子集:选出特征的子集,能够比较准确的代表原来的特征.马尔科夫毯(MB)是贝叶斯网络(BN)的最有特征子集. 推测贝叶斯网络的网络结构是NP问题.贝叶斯网络中一个节点T的马尔科夫毯是其父节点,子 ...

  3. easy ui 验证框的使用

    Easy ui 插件之validatebox missingMessage:未填写时显示的信息validType:验证类型见下示例invalidMessage:无效的数据类型时显示的信息require ...

  4. js 滚动页面

    $(‘html, body’).animate({ scrollTop: 0}, ‘slow’);

  5. php form 图片上传至服务器上

    本文章也是写给自己看的,因为写的很简洁,连判断都没有,只是直接实现了能上传的功能. 前台: <form action="upload.php" method="PO ...

  6. wchat_t与char互转

     C++ Code  1234567891011121314151617181920212223242526   //窄字符转宽字符 void ConvertA2W(wchar_t* the_strw ...

  7. poj 3281(网络流+拆点)

    题目链接:http://poj.org/problem?id=3281 思路:设一个超级源点和一个超级汇点,源点与食物相连,饮料与汇点相连,然后就是对牛进行拆点,一边喜欢的食物相连,一边与喜欢的饮料相 ...

  8. 基础知识《十四》Java异常的栈轨迹fillInStackTrace和printStackTrace的用法

    本文转自wawlian 捕获到异常时,往往需要进行一些处理.比较简单直接的方式就是打印异常栈轨迹Stack Trace.说起栈轨迹,可能很多人和我一样,第一反应就是printStackTrace()方 ...

  9. Mininet加强版——DOT(分布式OpenFlow试验平台)

    前言 之前在做SDN实验的时候,需要用到包含2000+个交换机的fattree拓扑,当时用的是mininet,生成整个拓扑需要十五六个小时,最终在异常艰苦的环境下做完了实验,之后听说了有DOT(Dis ...

  10. 【BZOJ3522】[Poi2014]Hotel 树形DP

    [BZOJ3522][Poi2014]Hotel Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房 ...