题目大概说要让n个骑士坐成一圈,这一圈的人数要是奇数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座。

双连通图上任意两点间都有两条不重复点的路径,即一个环。那么,把骑士看做点,相互不仇恨的骑士间连边,能坐在一圈骑士的肯定在同一个点双连通分量上。

不过还有个条件是人数要大于2:

  • 有这么一个结论:如果一个双连通分量存在奇圈(点数为奇数的环),那么这个双连通分量里所有点一定会包含在某一个奇圈内。
  • 大概是因为,双连通分量里面点为奇数个显然都包含在奇圈里;而如果是偶数个,一部分就包含在那个找到的奇圈,而剩下的偶数-奇数=奇数个点一定也形成一个奇圈。
  • 这样只要判断双连通分量是否存在奇圈即可。而存在奇圈是图是否为二分图的充分必要条件,而判断是否为二分图可以用染色法。

因此这题就是找双连通分量,找到一个双连通分量后,染色判断它是否包含奇圈,如果是双连通分量内所有点都能入座。

要注意的是一个点能属于多个点双连通分量。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 1111
#define MAXM 1111111
struct Edge{
int v,flag,next;
}edge[MAXM<<];
int NE,head[MAXN];
void addEdge(int u,int v){
edge[NE].v=v; edge[NE].flag=;
edge[NE].next=head[u]; head[u]=NE++;
} int n,ans[MAXN]; int dn,dfn[MAXN],low[MAXN];
int stack[MAXM],top;
int tag[MAXN],color[MAXN]; bool dfs(int u){
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(!tag[v]) continue;
if(color[v]==color[u]) return ;
if(color[v]==-){
color[v]=!color[u];
return dfs(v);
}
}
return ;
} void tarjan(int u){
dfn[u]=low[u]=++dn;
for(int i=head[u]; i!=-; i=edge[i].next){
if(edge[i].flag) continue;
edge[i].flag=edge[i^].flag=;
stack[++top]=i; int v=edge[i].v; if(dfn[v]){
low[u]=min(low[u],dfn[v]);
continue;
} tarjan(v);
low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]){
memset(tag,,sizeof(tag));
int k;
do{
k=stack[top--];
tag[edge[k].v]=;
tag[edge[k^].v]=;
}while(edge[k^].v!=u);
memset(color,-,sizeof(color));
color[u]=;
if(dfs(u)){
for(int i=; i<=n; ++i){
if(tag[i]) ans[i]=;
}
}
}
}
} bool ishate[MAXN][MAXN];
int main(){
int m;
while(~scanf("%d%d",&n,&m) && (n||m)){
memset(ishate,,sizeof(ishate));
int a,b;
while(m--){
scanf("%d%d",&a,&b);
ishate[a][b]=ishate[b][a]=;
} NE=;
memset(head,-,sizeof(head));
for(int i=; i<=n; ++i){
for(int j=i+; j<=n; ++j){
if(i==j) continue;
if(!ishate[i][j]){
addEdge(i,j);
addEdge(j,i);
}
}
} memset(ans,,sizeof(ans));
dn=; memset(dfn,,sizeof(dfn));
top=;
for(int i=; i<=n; ++i){
if(dfn[i]==) tarjan(i);
} int res=;
for(int i=; i<=n; ++i){
if(!ans[i]) ++res;
}
printf("%d\n",res);
}
return ;
}

POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)的更多相关文章

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

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

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

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

  3. POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈

    题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...

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

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

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

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

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

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

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

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

  8. Knights of the Round Table-POJ2942(双连通分量+交叉染色)

    Knights of the Round Table Description Being a knight is a very attractive career: searching for the ...

  9. [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)

    建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点                             ...

  10. poj2942 Knights of the Round Table[点双+二分图染色]

    首先转化条件,把无仇恨的人连边,然后转化成了求有哪些点不在任何一个奇环中. 一个奇环肯定是一个点双,所以想到处理出所有点双,但是也可能有的点双是一个偶环,有的可能是偶环和奇环混杂,不好判. 考察奇环性 ...

随机推荐

  1. October 6th 2016 Week 41st Thursday

    The outer world you see is a reflection of your inner self. 你拥有什么样的内心,你就会看到什么样的世界. And we eventually ...

  2. osgi学习

    Bundle可以被动态地安装.启动.停止和卸载.Bundle是服务(Service)和组件(Component)的载体.在OSGi中,每个Bundle都有自己独立于其他Bundle的ClassLoad ...

  3. clustershell

    .安装 yum install clustershell .配置ssh无密码登录 .配置/etc/hosts 在hosts中文件中将ip和主机名对应起来,使用比较方便 .配置关键文件 clusters ...

  4. 解决VS2010 C++ DLL不能断点调试的问题

    问题产生的过程是这样的,向exe项目(CSharp)中添加dll工程(c++开发)的引用,并将引用工程的属性“Link Library Dependencies”的值设为true,这样,在不加入lib ...

  5. STL_advance distance prev next

    template<class InputIterator> typename iterator_traits<InputIterator>::difference_type d ...

  6. markdown思维导图笔记

  7. 三、jQuery--jQuery实践--搜索框制作

    input标签讲解 <input/>作为按钮的type属性:button.submit(后面会有二者对比分析)

  8. ListView + PopupWindow实现滑动删除

    原文:ListView滑动删除 ,仿腾讯QQ(鸿洋_) 文章实现的功能是:在ListView的Item上从右向左滑时,出现删除按钮,点击删除按钮把Item删除. 看过文章后,感觉没有必要把dispat ...

  9. grep -i 不区分大小写

    # rpm -qa|grep -i "mysql" MySQL-server--.rhel5.x86_64 MySQL-test--.rhel5.x86_64 MySQL-embe ...

  10. 重温WCF之数据契约和序列化(四)

    一.数据契约 1.使用数据协定可以灵活控制哪些成员应该被客户端识别. [DataContract] public class Employee { [DataMember] public string ...