POJ2942 Knights of the Round Table 双连通分量+二分图+奇圈判断

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

有n个骑士,其中有m对关系恶劣

现在开会要坐在圆桌上面,可以做很多张圆桌,但是关系恶劣的两人不能坐在相邻位置,现在问你有多少个骑士不能参加会议。将关系不恶劣的其实连边

首先这道题目为什么是双联通分量而不是边双联通,因为圆桌,是一个环,每两个点之间存在两条(或以上)点不重复的路径,因此是一个双联通分量,一个联通分量重的骑士,可能组成一个圆桌会议。

至于一个联通分量的中的骑士能不能组成一个圆桌,则是二分图的知识,首先我们知道二分图的意义。一条边的两个端点能够染上不同的颜色,而由于题目中要我们找奇圈,可以知在奇圈中有一条边两端点颜色相同,这就破坏了二分图性质。因此如果一个联通分量是二分图则无法组成圆桌会议。否则能够组成圆桌会议。

至于其中那些点能够参加会议呢?并不是所有联通分量中的点都在奇圈中的,这是我们要注意的,首先我们了解到联通分量重有几圈,因此我们要从中找圈上的点


Knights of the Round Table
Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 7684 Accepted: 2387

Description

Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very surprising that in recent years the kingdom of King Arthur has experienced an unprecedented increase in the number of knights. There are so many knights now, that it is very rare that every Knight of the Round Table can come at the same time to Camelot and sit around the round table; usually only a small group of the knights isthere, while the rest are busy doing heroic deeds around the country. 

Knights can easily get over-excited during discussions-especially after a couple of drinks. After some unfortunate accidents, King Arthur asked the famous wizard Merlin to make sure that in the future no fights break out between the knights. After studying the problem carefully, Merlin realized that the fights can only be prevented if the knights are seated according to the following two rules:
  • The knights should be seated such that two knights who hate each other should not be neighbors at the table. (Merlin has a list that says who hates whom.) The knights are sitting around a roundtable, thus every knight has exactly two neighbors.
  • An odd number of knights should sit around the table. This ensures that if the knights cannot agree on something, then they can settle the issue by voting. (If the number of knights is even, then itcan happen that ``yes" and ``no" have the same number of votes, and the argument goes on.)
Merlin will let the knights sit down only if these two rules are satisfied, otherwise he cancels the meeting. (If only one knight shows up, then the meeting is canceled as well, as one person cannot sit around a table.) Merlin realized that this means that there can be knights who cannot be part of any seating arrangements that respect these rules, and these knights will never be able to sit at the Round Table (one such case is if a knight hates every other knight, but there are many other possible reasons). If a knight cannot sit at the Round Table, then he cannot be a member of the Knights of the Round Table and must be expelled from the order. These knights have to be transferred to a less-prestigious order, such as the Knights of the Square Table, the Knights of the Octagonal Table, or the Knights of the Banana-Shaped Table. To help Merlin, you have to write a program that will determine the number of knights that must be expelled. 

Input

The input contains several blocks of test cases. Each case begins with a line containing two integers 1 ≤ n ≤ 1000 and 1 ≤ m ≤ 1000000 . The number n is the number of knights. The next m lines describe which knight hates which knight. Each of these m lines contains two integers k1 and k2 , which means that knight number k1 and knight number k2 hate each other (the numbers k1 and k2 are between 1 and n ). 

The input is terminated by a block with n = m = 0 . 

Output

For each test case you have to output a single integer on a separate line: the number of knights that have to be expelled. 

Sample Input

5 5
1 4
1 5
2 5
3 4
4 5
0 0

Sample Output

2

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdio>

using namespace std;

#define MAXN 2100
#define MAXM 2001000

struct node
{
    int to,next;
}edge[MAXM];

bool maps[MAXN][MAXN];
int head[MAXN],en;
int n,m;
int vis[MAXN],dfn[MAXN],low[MAXN],color[MAXN];
int stack[MAXN],top;
bool in[MAXN],tag[MAXN];

void add(int a,int b)
{
    edge[en].to=b;
    edge[en].next=head[a];
    head[a]=en++;
    edge[en].to=a;
    edge[en].next=head[b];
    head[b]=en++;
}

bool func(int pre,int u)
{
	color[u]=1;
	bool ok=0;
	for(int i=head[u];i!=-1;i=edge[i].next)
	{
		int v=edge[i].to;
		if(in[v])
		{
			if(color[v]==1)
			{
				if(v!=pre)
					ok=true;
			}
			else
			{
				if(func(u,v))
					ok=true;
			}
		}
	}
	if(ok)
		tag[u]=1;
	return ok;
}

bool bipartite(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])
		{
		    if(color[v]==0)
		    {
                if(!bipartite(v,-c))
                    return false;
		    }
			else
				if(color[v]==color[u])
					return false;
		}
    }
    return true;
}

void find(int u,int fat)
{
	memset(in,0,sizeof(in));
	in[fat]=1,in[u]=1;
	while(stack[top-1]!=u)
	{
		in[stack[top-1]]=1;
		top--;
	}
	memset(color,0,sizeof(color));
	if(!bipartite(u,1))
	{
		memset(color,0,sizeof(color));
		func(fat,fat);
	}

}


void dfs(int u,int fat,int dis)
{
    stack[top++]=u;
    dfn[u]=low[u]=dis;
    vis[u]=1;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!vis[v])
        {
            dfs(v,u,dis+1);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u]) find(v,u);
        }
        else
           low[u]=min(low[u],dfn[v]);
    }
}

void tarjan()
{
    top=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
		if(!vis[i]) dfs(i,-1,1);
}

void solve()
{
    int x,y;
    memset(maps,0,sizeof(maps));
    memset(tag,0,sizeof(tag));
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        maps[x][y]=maps[y][x]=1;
    }
    memset(head,-1,sizeof(head)),en=0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(!maps[i][j]) add(i,j);
     tarjan();
     int ans=n;
     for(int i=1;i<=n;i++)
     {
		if(tag[i]) ans--;
	 }
	 printf("%d\n",ans);

}


int main()
{
    while(~scanf("%d%d",&n,&m)&& n+m )
        solve();
    return 0;
}


poj2942】圆桌骑士Knights of the Round Table双连通分量】【二分图】【 传送门:http://poj.org/problem?id=2942 尽管我承认这题我几乎是对着书抄的代码(因为我还不熟- -),但是我还是WA了三次- -数组又没清零。 基本思想就是: 首先把不互相憎恨的骑士连边。 求双连通分量bcc。 判断每个bcc是不是二分图,是的话这个二分图里的骑士都没法参加会议。因为形不成就是数个点连成的啦~ 二分图是不可能有的(有的话 阅读详情

相关推荐

POJ-2942 Knights of the Round Table(补图+双连通分量++染色判断二分图+结论)

链接:http://poj.org/problem?id=2942 题意:多组样例。亚瑟王要召唤骑士在圆桌会议。n个骑士,m个憎恨关系,一个骑士不能和他憎恨的骑士坐在一块。亚瑟王要求来开会的骑士的个数必须是数,在此条件下,求开除最少的骑士。(注意一个骑士不能开会,至少三个骑士才能开会。) 思路:我们建补图,这样有边的人都能做一块,然后再求点双,求出点双后,再判断能不能形成。这里有现成的结...

birdmanqin的博客 321

POJ2942 Knights of the Round Table双连通分量,逆图,

题目链接: poj2942 题意: 有n个人,可以开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数只能为书 问有多少人不能参加 解题思路: 首先构图,将所有的仇视关系视为一条边,最后再取已经得到的图的逆图, 这样图上连接的边就代表可以相邻而坐的关系 然后就是找了,首先就是要

旧时光 1250

POJ - 2942Knights of the Round Table(点双连通分量二分图判断

题干: Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very surprisin...

xuanweiace的博客 619

POJ 2942 Knights of the Round Table (点-双连通分量 + 交叉法染色判二分图

POJ 2942 Knights of the Round Table  链接:http://poj.org/problem?id=2942 题意:亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1、 相互憎恨的两个骑士不能坐在直接相邻的2个位置; 2、 出席会议的骑士数必须是数,这是为了

SIOFive的专栏 1204

POJ2942 Knights of the Round Table

POJ2942 Knights of the Round Table 开始看错题了,“某些骑士无法出席所有会议”并不是无法出席某个会议, 我们尝试建图,按照题目给的条件,我们可以将相互仇恨的骑士之间建边。那么骑士可以坐在一起的条件就是他们之间没有边。所以我们建出这个图的补图会使解题更加方便。 然后我们可以发现一些显然的事情,比如度数<=1的点一定参加不了。一条链上的点也一定参加...

weixin_30593261的博客 79

POJ2942-Knights of the Round Table

全解题报告索引目录 -> 【北大ACM – POJ试题分类】 转载请注明出处:http://exp-blog.com ------------------------------------------------------------------------- 大致题意: 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结...

ζёСяêτ - 小優YoU 1万+

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

http://poj.org/problem?id=2942 题意: 有N个骑士,给出某些骑士之间的仇恨关系,骑士们开会时会围坐在一个圆桌旁。一次会议能够顺利举行,要满足两个条件:1:任意相互憎恨的两个骑士不能相邻 2:开会人数为大于2的数 若某个骑士任何会议都不能参加,那么就必须将他踢出,给出骑士之间的仇恨关系,问最少需要踢出多少个骑士? 思路: 题目要求踢出的人最少,那么

2299

POJ-2942 Knights of the Round Table

题目: http://poj.org/problem?id=2942 题意: 骑士们要开会,有的骑士之间有矛盾,要求每次会议的人数是数并且做成一之后相邻的骑士之间不能有矛盾,问有多少骑士一次会议都无法参加而被开除? 思路: 这两天一直在做这道题,前面做的双连通分量的题都是为了做这道,确实出的很好。 这道题首先想到的是所有骑士之间建立补图,就是将没有矛盾的骑士之间连线,表示他们可以坐

MyWorld 526

POJ 2942 - Knights of the Round Table(双连通图 Tarjan + 二分判定)

POJ 2942 - Knights of the Round Table(双连通图 Tarjan + 二分判定) ACM 题目地址:  POJ 2942 - Knights of the Round Table 题意:  有N个骑士,给出某些骑士之间的仇恨关系,骑士们开会时会围坐在一个圆桌旁。一次会议能够顺利举行,要满足两个条件: 任意相互憎恨的两个骑士不能相邻开会人

水果君の日常 1437

poj 2942 Knights of the Round Table(点双连通分量)

题目链接:http://poj.org/problem?id=2942 转载自:https://blog.csdn.net/lyy289065406/article/details/6756821 大致题意: 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1、 相互憎恨的两...

agyohust791263的博客 270

poj 2942 Knights of the Round Table

题意:在一张无向图中,问有多少个点不属于任意一个,孤立点不属于 首先明确两个定理: 定理1:对于一个点双连通分量,如果找个一个那么这个分量的其他点也必然在某个内。    证明很简单,设ab是一个上的点,c不属于这个,设c到a和边数为m到b的边数为n,若m+n为数,则c位于由这个环除ab外的其他边(偶数条)构成一个环,如果m+n为偶数,那么c到ab的路径与ab边构

新博客地址:sensirly.github.io 695

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

题目链接 题意 有N个骑士,每个骑士有自己不喜欢的人,你需要选择数个骑士开一个圆桌会议,每个骑士不能和自己不喜欢的人挨着坐。 问需要删除那些人,这些人不能组成圆桌会议 思路 按照补图建边求双连通分量,然后判断双连通分量中是否有 判断是否存在可以判断二分图,如果不存在二分图则存在 统计可以组成圆桌会议的人,总数减去即可 #include <iostream> #incl...

Running Bit. 391

POJ2942 UVA1364 Knights of the Round Table 圆桌骑士

POJ2942洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则题意变为求图中不在任何环(结点数为数的环)中的点的数量。 一个环上的点一定属于一个双连通分量(两两都有两条路径可达) 那么什么时候双连通分量中没有环呢? 显然,当双连通分...

baben4194的博客 212

点连通分量-poj-2942Knights of the Round Table

点连通分量的例题 贴一下点连通分量的模板解释一下这个模板。 把父节点和子节点都存一个时间戳。然后不断dfs,同时更新lowver,即父节点 最早的时间戳 如果更新成功,那就把栈里的边都取出来,放进同一个连通分量里面 如果子节点已经被访问过了,说明形成了一个环,更新lowver,即父节点 最早的时间戳,并且返回该时间戳的值 同时里面加上一个判断子节点个数的child变量。如果一个节点的父亲是-1而且只有一个孩子,那么这个根节点并不是割点

起一个长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长的名字 425

poj 2942 Knights of the Round Table(无向图的双连通分量+二分图判定)

无向图的双连通分量以及二分图的判定

GODSPEED 752

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

题目大概说要让n个骑士坐成一,这一的人数要是数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座。 双连通图上任意两点间都有两条不重复点的路径,即一个环。那么,把骑士看做点,相互不仇恨的骑士间连边,能坐在一骑士的肯定在同一个点双连通分量上。 不过还有个条件是人数要大于2: 有这么一个结论:如果一个双连通分量存在(点数为数的环),那么这个双连...

dengliugong3918的博客 153

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

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

weixin_30672295的博客 148

poj2942 Knights of the Round Table

http://www.elijahqi.win/archives/3598 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun th...

Elijahqi 288

POJ - 2942 Knights of the Round Table(点双缩点+二分图判定)

题目链接:点击查看 题目大意:国王要在圆桌上召开骑士会议,但是有若干对骑士之间互相憎恨。出于各种各样怪的原因,每次开会都必须有以下要求: 相互憎恨的两个骑士不能坐在相邻的两个位置 为了让投票表决议题时都能有结果(不平票),出席会议的骑士数必须是数 如果有某个骑士无法出席任何会议,则国王会为了世界和平把他踢出骑士团。现在给定n个骑士和m个憎恨关系,求出至少需要踢掉多少个骑士 题目分析:很...

Falcon的博客 461
上一篇: Ural1774 Barber of the Army of Mages 最大流
下一篇: Ural1553 Caves and Tunnels 树链剖分
Albafica
博客等级 码龄15年 98粉丝 359原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值