【打CF,学算法——三星级】CodeForces 216B Forming Teams (图论)

该博客详细介绍了如何解决CodeForces上的一道图论问题——216B Forming Teams。内容包括问题描述、解题思路和代码实现。通过构建敌对关系图,分析环与链的情况,找到最小数量的板凳人员以满足团队组建条件。解题关键在于判断奇数长度环并优化链的分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【CF简介】

提交链接:CF 216B


题面:

B. Forming Teams
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

One day n students come to the stadium. They want to play football, and for that they need to split into teams, the teams must have an equal number of people.

We know that this group of people has archenemies. Each student has at most two archenemies. Besides, if student A is an archenemy to student B, then student B is an archenemy to student A.

The students want to split so as no two archenemies were in one team. If splitting in the required manner is impossible, some students will have to sit on the bench.

Determine the minimum number of students you will have to send to the bench in order to form the two teams in the described manner and begin the game at last.

Input

The first line contains two integers n and m (2 ≤ n ≤ 100, 1 ≤ m ≤ 100) — the number of students and the number of pairs of archenemies correspondingly.

Next m lines describe enmity between students. Each enmity is described as two numbers ai and bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — the indexes of the students who are enemies to each other. Each enmity occurs in the list exactly once. It is guaranteed that each student has no more than two archenemies.

You can consider the students indexed in some manner with distinct integers from 1 to n.

Output

Print a single integer — the minimum number of students you will have to send to the bench in order to start the game.

Examples
Input
5 4
1 2
2 4
5 3
1 4
Output
1
Input
6 2
1 4
3 4
Output
0
Input
6 6
1 2
2 3
3 1
4 5
5 6
6 4
Output
2












--------------------------------------------------------------------------------------做完再看------------------------------------------------------------------------------------------------------------------------------





题意:

    给定n个朋友,m个敌对关系。敌对关系是相互的,即a和b是敌对的,那么b和a也是敌对的,具有敌对关系的两个人不能在一个小组,一个人最多只有两个敌对对象。现在要求将所有人分成两个小组,使得两组人数相同,且内部不具备敌对关系,且做板凳(即未被选中的人的数量尽量少)。


解题:

    将题目给定的敌对关系构造成图,可以发现,联通块要么是环,要么是链,要么就是孤立点(因为一个点最多只有2的度数)。分析可以比较容易得出,奇数长度的环,必须牺牲一个人做板凳,因为选出的len-1人分为两个小组,必有一人与两个小组的人都存在敌对关系,故而找奇环,发现则做板凳人数数量加一。如果是链,可以i,i+1分别分配给两个小组,就不会出现敌对关系,但奇数链会损失一个,但不同链之间无敌对关系,因此可以链接所有链,最终链长度为奇数,则损失一个。

     注意:找奇环的过程,开始写错了,应该是计算一个联通块上的总度数,并记录是否出现了度数为1或者为0的点,没有则判定为环,奇环的总度数/2是奇数,可以通过这点判断奇环。


代码:


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
bool vis[105];
bool con[105][105];
int degree[105];
int minuss=0,n,m,sum;
bool flag;
void dfs(int x,int pre)
{
	vis[x]=1;
	if(degree[x]==1||degree[x]==0)
		flag=1;
	sum+=degree[x];
    for(int i=1;i<=n;i++)
	{
		if(!vis[i]&&con[x][i]&&i!=pre)
        {
			dfs(i,x);
		}
	}
}
int main()
{
	int a,b,ans;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		degree[a]++;
		degree[b]++;
		con[a][b]=con[b][a]=1;
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
        {
			sum=0;
			flag=0;
			dfs(i,-1);
			if(!flag)
		    {
				if(sum/2%2)
				minuss++;
			}
		}
	}
	ans=minuss+(n-minuss)%2;
	printf("%d\n",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值