POJ2942-Knights of the Round Table
来源:互联网 发布:制作菜单图片软件 编辑:程序博客网 时间:2024/06/06 01:46
题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1。2.总人数为奇数。3.有仇恨的骑士不能挨着坐。问有几个骑士不能和任何人形成任何的圆圈。
有很多需要注意的点
①他给我们相互憎恨的骑士线段,我们先变成补图,也就是相连的是可以在一起坐的,不相连的是不能在一起坐的。也就是说我们
要从相连的当中找。 (先求补图)
②他让我们求的是任何搭配都不行的骑士的数量,就是说完全不能开会的,我们要遍历各种情况。
③tarjan求双联通,每求出一个双联通区,我们要先判断是否为奇数个,利用二分染色法判断判断是不是奇数个。(题目要求为奇数个人)。如果是
记录所有的成员,这些成员都不用踢出去,我们再找继续找其他的强连通图即可。
基本思路:
①我们一般做这种题,都会往tarjan上靠,对于这道题,如果我们想用tarjan来做,必然是说明部分点可以合并,也就是相互信任的点可以合并。而题目给的
是相互憎恨的,所以我们要求补图
②对于判断一个图是否为奇圈,就是用染色法判断即可。
③什么时候判断,也就是每次找出一个强连通是就要判断一次,因为这样省空间省时间。
④题目一定要读懂,是任何一个会议都不能参加的。人数要>3的。
#include <iostream>
#include <queue>
#include <string.h>
#include <stdio.h>
using namespace std;
const int maxn=1005;
const int maxm=1000005;
struct Edge
{
int to,next;
} edge[maxm];
int head[maxn],tot;
int g[maxn][maxn];
int low[maxn],dfn[maxn],Stack[maxn],belong[maxn];
int Index,top;
int block;
bool Instack[maxn];
bool can[maxn];
bool ok[maxn];
int tmp[maxn];
int cc;
int color [maxn];
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!=-1; i=edge[i].next)
{
int v=edge[i].to;
if(!ok[v])
continue;
if(color[v]!=-1)
{
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!=-1; 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=0;
memset(ok,false,sizeof(ok));
do
{
vn=Stack[--top];
belong[vn]=block;
Instack[vn]=false;
ok[vn]=true;
tmp[cc++]=vn;
}
while(v!=vn);
ok[u]=1;
memset(color,-1,sizeof(color));
if(!dfs(u,0))
{
can[u]=true;
while(cc--)
can[tmp[cc]]=true;
}
}
}
else if(low[u]>dfn[v])
low[u]=dfn[v];
}
}
void init()
{
tot=0;
memset(head,-1,sizeof(head));
memset(g,0,sizeof(g));
memset(low,0,sizeof(low));
memset(can,0,sizeof(can));
memset(dfn,0,sizeof(dfn));
memset(Instack,false,sizeof(Instack));
Index=block=top=0;
}
int main()
{
int n,m,k1,k2;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
init();
for(int i=1; i<=m; i++)
{
cin>>k1>>k2;
g[k1][k2]=g[k2][k1]=1;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
if(i!=j&&!g[i][j])
{
addedge(i,j);
}
}
for(int i=1; i<=n; i++)
if(!dfn[i])
tarjan(i,-1);
int ans=n;
for(int i=1; i<=n; i++)
if(can[i])
ans--;
cout<<ans<<endl;
}
return 0;
}
- POJ2942--Knights of the Round Table
- poj2942 Knights of the Round Table
- poj2942 Knights of the Round Table
- poj2942 Knights of the Round Table
- POJ2942-Knights of the Round Table
- poj2942:Knights of the Round Table(Tarjan)
- poj2942点双连通奇圈-二分图判断Knights of the Round Table
- poj2942 Knights of the Round Table,点双连通分量,奇环判断
- poj2942--F - Knights of the Round Table(圆桌骑士,经典连通分量)
- poj2942 Knights of the Round Table,无向图点双联通,二分图判定
- 【poj2942】圆桌骑士Knights of the Round Table【双连通分量】【二分图】【奇圈】
- POJ2942 Knights of the Round Table(双联通分量+奇圈判断)
- POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈
- Knights of the Round Table-POJ2942(双连通分量+交叉染色)
- 【POJ2942】Knights of the Round Table-点双连通分量+判断奇环
- POJ2942-Knights of the Round Table (双联通+判断奇环)
- Knights of the Round Table
- Knights of the Round Table
- 关于从fragment中startActivity后从OnActivityResult中接收的问题
- 简单谈谈ActiveMQ的两种消费方式
- Glide入门教程——1.入门简介
- 轻松又酷炫地实现弹幕效果——手把手教学
- 任正非:不要在微信里消耗你的人生和青春
- POJ2942-Knights of the Round Table
- 浅谈Oracle select for update
- Spring boot 下使用RabbitMQ报错:406
- 如何去掉String[]数组中的重复项
- Java中关于HashMap的元素遍历的顺序问题
- 【整理】Word OpenXML常用标签
- 面向对象程序设计---创建对象
- Windows虚拟内存简介
- 【安全牛学习笔记】XSS- 键盘记录器和反射型XSS