题目链接:

poj2942

题意:

有n个人,能够开多场圆桌会议

这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置

且每场圆桌会议的人数仅仅能为奇书

问有多少人不能參加

解题思路:

首先构图,将全部的仇视关系视为一条边,最后再取已经得到的图的逆图,

这样图上连接的边就代表能够相邻而坐的关系

然后就是找奇圈了,首先就是要找图中的环(点双连通分量)

这个环为奇环的条件:不是二分图||这个环中的部分点属于其它奇环

这个推断能够通过将已找到的环进行dfs黑白染色推断

最后不在奇环内的总和即是答案

至于为什么要找的是点双连通分量而不是边双连通分量 能够试试这组数据:

6 8

1 4

1 5

1 6

2 4

2 5

2 6

3 6

4 5

0 0



得到的逆图是这种:

假设是电双连通分量(拆开割点)则分为(1 2 3)和(3 4 5 6)两部分

而假设是边双连通分量(去掉割边)则仅仅有(1 2 3 4  5 6 )一部分了

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1050
using namespace std;
struct node{
int to,next;
}edge[2000500];
int head[maxn],ss;
int map[maxn][maxn]; int in[maxn],odd[maxn],temp[maxn];
int color[maxn]; int dfn[maxn],low[maxn],num;
int insta[maxn],sta[maxn],top;
int n; void init()
{
memset(dfn,0,sizeof(dfn));
memset(head,-1,sizeof(head));
memset(insta,0,sizeof(insta));
memset(map,0,sizeof(map));
memset(odd,0,sizeof(odd));
top=num=ss=0;
} void addedge(int a,int b)
{
edge[ss]=(node){b,head[a]};
head[a]=ss++;
} int dfs(int u,int c)
{
color[u]=c;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!in[v])
continue;
if(color[v]==c)
return 1;
else if(color[v])
continue;
else if(dfs(v,3-c))
return 1;
}
return 0;
} void Tarjan(int u,int pre)
{
dfn[u]=low[u]=++num;
insta[u]=1;
sta[top++]=u;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==pre)
continue;
if(!dfn[v])
{
Tarjan(v,u);
low[u]=min(low[u],low[v]); if(dfn[u]<=low[v])
{
int s=0,d=-1;
memset(in,0,sizeof(in));
while(d!=v) //注意是v 点双连通的还有一种写法,总之要注意割点能够属于多个连通分量
{
d=sta[--top];
in[d]=1;
insta[d]=0; //不能让u=0
temp[s++]=d;
}
in[u]=1;
memset(color,0,sizeof(color));
if(dfs(u,1)) //黑白染色判定
{
odd[u]=1;
while(s!=0)
odd[temp[--s]]=1;
}
}
}
else if(insta[v])
low[u]=min(low[u],dfn[v]);
}
} void solve()
{
for(int i=1;i<=n;i++)
if(!dfn[i])
Tarjan(i,-1);
int ans=0;
for(int i=1;i<=n;i++)
if(!odd[i])
ans++;
printf("%d\n",ans);
} int main()
{
// freopen("in.txt","r",stdin);
int m,a,b;
while(scanf("%d%d",&n,&m)&&(m+n))
{
init();
while(m--)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&!map[i][j]) //取逆图
addedge(i,j);
solve();
}
return 0;
}

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. poj 2942 Knights of the Round Table(点双连通分量+二分图判定)

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

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

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

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

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

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

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

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

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

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

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

  9. POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)

    题目大概说要让n个骑士坐成一圈,这一圈的人数要是奇数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座. 双连通图上任意两点间都有两条不重复点的路径,即一个环.那么,把骑士看做点,相 ...

随机推荐

  1. 谈一次java web系统的重构思路

    ——略谈Java web软件如何提供二次开发接口 接手公司的一个Java web软件产品,该软件采用传统的dwr框架.dwr框架相当于一个中间层,使得javascript能够识别Java类对象,进而能 ...

  2. OpenCV二维Mat数组(二级指针)在CUDA中的使用

    CUDA用于并行计算非常方便,但是GPU与CPU之间的交互,比如传递参数等相对麻烦一些.在写CUDA核函数的时候形参往往会有很多个,动辄达到10-20个,如果能够在CPU中提前把数据组织好,比如使用二 ...

  3. 全排列Permutations

    描述 Given a collection of numbers, return all possible permutations.For example,[1,2,3] have the foll ...

  4. Vue.js优雅的实现列表清单的操作

        一.Vue.js简要说明 Vue.js (读音 /vjuː/,类似于 view) 是一套构建用户界面的渐进式框架.与前端框架Angular一样, Vue.js在设计上采用MVVM模式,当Vie ...

  5. 《Linux命令行与shell脚本编程大全》 第七章理解Linux文件权限

    Linux沿用了Unix文件权限的方法,允许用户和组根据每个文件和目录的安全性设置来访问文件. 用户权限通过创建用户时分配的用户ID(UID)来跟踪的.每个用户有唯一的ID,但是登录时用的不是UID, ...

  6. Spring ioc与aop的理解

    一 spring的特点 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易 ...

  7. [转载] Cassandra入门 框架模型 总结

    转载自http://asyty.iteye.com/blog/1202072 一.Cassandra框架二.Cassandra数据模型 Colum / Colum Family, SuperColum ...

  8. TensorFlow(三)---------正则化

    TensorFlow正则化经常被用于Deep-Learn中,泛化数据模型,解决过拟合问题.再深度学习网络只有在有足够大的数据集时才能产生惊人的学习效果.当数据量不够时,过拟合的问题就会经常发生.然而, ...

  9. Android设置屏幕方向

    设置方法:在AndroidManifest.xml中的Activity里加一个属性android:screenOrientation.例如设置该Activity为横向 <activity and ...

  10. Android开发之漫漫长途 番外篇——自定义View的各种姿势1

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...