圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边)。

求无论如何都不能参加会议的骑士个数。只需求哪些骑士是可以参加的。

我们求原图的补图:只要不是敌人的两个人就连边。

在补图的一个奇圈里(由奇数个点组成的环)每个点都是可以参加的。而一个奇圈一定在点双连通分量里,所以我们把原图的每个点双连通分量找出来,然后判断是否有奇圈。用到了几个引理:

非二分图至少有一个奇圈。

点双连通分量如果有奇圈,那么每个点都在某个奇圈里(不一定是同一个)。

于是问题转化为对每个点双连通分量,判断它是不是二分图,如果不是,那就把它里面所有点都标记为可行,最后用总数减去可行的就是答案(无论如何都不能参加会议的骑士个数)。

二分图染色就是dfs,对一个点染色后,对其相邻点染上与自己不同的颜色,如果相邻点已经染过,就判断其颜色是否和自己相同,是则说明不是二分图,否则跳过该相邻点。直到全部染完。

#include<cstdio>
#include<cstring>
const int N = ;
const int M = ;
struct Edge
{
int to,next;
}edge[M];
int head[N],tot;
int Low[N],DFN[N],Stack[N],Belong[N];
int Index,top;
int block;//点双连通分量的个数
bool Instack[N];
bool can[N];
bool ok[N];//标记
int tmp[N];//暂时存储双连通分量中的点
int cc;//tmp的计数
int color[N];//染色
void addedge(int u,int v)
{
edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}
bool dfs(int u,int col)//染色判断二分图
{
color[u] = col;
for(int i = head[u];~i;i = edge[i].next)
{
int v = edge[i].to;
if( !ok[v] )continue;
if(~color[v])
{
if(color[v]==col)return false;
continue;
}
if(!dfs(v,!col))return false;
}
return true;
}
void Tarjan(int u,int pre)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u];~i;i = edge[i].next)
{
v = edge[i].to;
if(v == pre)continue;
if( !DFN[v] )
{
Tarjan(v,u);
if(Low[u] > Low[v])Low[u] = Low[v];
if( Low[v] >= DFN[u])
{
block++;
int vn;
cc = ;
memset(ok,false,sizeof ok);
do
{
vn = Stack[--top];
Belong[vn] = block;
Instack[vn] = false;
ok[vn] = true;
tmp[cc++] = vn;
}
while( vn!=v );
ok[u] = ;
memset(color,-,sizeof(color));
if( !dfs(u,) )
{
can[u] = true;
while(cc--)can[tmp[cc]]=true;
}
}
}
else if(Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
}
void solve(int n)
{
memset(DFN,,sizeof DFN);
memset(Instack,false,sizeof Instack);
Index = block = top = ;
memset(can,false,sizeof can);
for(int i = ;i <= n;i++)
if(!DFN[i])
Tarjan(i,-);
int ans = n;
for(int i = ;i <= n;i++)
if(can[i])
ans--;
printf("%d\n",ans);
}
void init()
{
tot = ;
memset(head,-,sizeof head);
}
int g[N][N];
int main()
{
int n,m,u,v;
while(scanf("%d%d",&n,&m),n)
{
init();
memset(g,,sizeof g);
while(m--)
{
scanf("%d%d",&u,&v);
g[u][v]=g[v][u]=;
}
for(int i = ;i <= n;i++)
for(int j = ;j <= n;j++)
if(i != j && g[i][j]==)
addedge(i,j);
solve(n);
}
return ;
}
  

【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)的更多相关文章

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

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

  2. POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]

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

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

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

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

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

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

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

  6. POJ - 2942 Knights of the Round Table (点双联通分量+二分图判定)

    题意:有N个人要参加会议,围圈而坐,需要举手表决,所以每次会议都必须是奇数个人参加.有M对人互相讨厌,他们的座位不能相邻.问有多少人任意一场会议都不能出席. 分析:给出的M条关系是讨厌,将每个人视作点 ...

  7. UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)

    题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向 ...

  8. POJ2942 Knights of the Round Table 点双连通分量 二分图判定

    题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...

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

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

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

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

随机推荐

  1. EncryptHelper

    public class EncryptHelper { public static string EncryptMd5Str(string str) { MD5 md5Obj = MD5.Creat ...

  2. 用django实现一个微信图灵机器人

    微信的post请求格式是xml,所以django需要做的就是将xml请求解析出来,把content发送到图灵机器人接口, 接口返回的json数据把主要内容给解析出来,然后重新封装成xml返回给微信客户 ...

  3. jdbc连接数据库总结

    jdbc支持多种数据库,比如说oracle, mysql, mssql,现在总结一下连接各种数据库的相关知识 1,mysql连接,代码如下 Class.forName("com.mysql. ...

  4. SPM12manual,统计部分(8-10)笔记

    fMRI model specifictaion GLM based 包括以下步骤:①明确GLM设计矩阵:②用经典或贝叶斯方法估计GLM参数:③利用对比向量检查结果,生成统计参数图(SPMs)以及后验 ...

  5. Generate Parentheses

    Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...

  6. C++ 中dynamic_cast&lt;&gt;的使用方法小结 -判断类型-rtti

    将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理          即会作一定的判断.        对指针进行dynamic ...

  7. Linux 退格键不回显

    在程序使用system("stty erase ^H");可以实现在输入状态下,按退格键删除字符,不回显. 调用tcsetattr修改linux基本输入的控制字符定义 //Linu ...

  8. 利用performance属性查看网页性能

    一般我们可以通过浏览器的调试工具-网络面板,或者代理工具查看网页加载过程中的各个阶段的耗时.而利用window.performance属性则可以获得更为精确的原始数据,以毫秒为单位,精确到微秒. pe ...

  9. Eclipse工作常见问题总结

    一.Eclipse常见快捷键使用 自动完成单词:Alt+/ 重命名:Shift+Alt+r(统一改变字段或方法名) 生成getter/setter方法: Shift+Alt+s,然后r 删除当前行:C ...

  10. The specified framework 'Microsoft.NETCore.App', version '1.0.1' was not found 解决办法

    环境:Centos 7 已经下载安装.NET Core 1.1 Microsoft .NET Core Shared Framework Host Version : Build : 928f77c4 ...