考试安排(染色法判定二分图)

本文介绍了一种解决俄罗斯学校考试调度问题的算法。该算法确保每个小学生能在两天内完成两个不同科目的选择性考试,且每个学生不会在同一天进行两场考试。通过使用图论中的二分图匹配概念,文章详细解释了如何判断是否可以在两天内安排所有考试,以及如何确定第一天应安排的考试数量。

Description
在俄罗斯学校里,小学生在离校之前必须做两个"选择性"考试。这意味着学校必须提供一些可选的考试。每个学生选择两个不同的科目。根据规则每个学生不允许在同一天完成两个考试。所以学校必须安排好这些考试。
学校为了不想让老师太辛苦监考,他们想在两天之内安排所有这些考试。在第一天安排一些考试,在第二天安排其它的考试。现要求你编写一个的程序来判断是否可以做到在两天内让每个学生都能参加他们选择的考试。
Input
第一行有两个整数N和M,N表示可供选择的考试科目数,M代表学生的人数。接下来的M行中分别描述一个学生选择的两门考试科目编号。
Output
如果安排方法存在,在第一行输出"Yes",在第二行输出在第一天必须安排的考试项目的数量(第一天安排尽可能多的考试);如果安排方法不存在,输出"No" 。
Sample Input
4 4
1 2
3 4
2 4
1 3
Sample Output
Yes
2
Hint
100%的数据:1≤N≤200,1≤m≤20000。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=40005;
int head[N],nxt[N],adj[N],tot,num[5];
void add(int u,int v)
{
	tot++;
	nxt[tot]=head[u];
	head[u]=tot;
	adj[tot]=v;
}
int num1,num2,vis[N];
inline int mx(int x,int y)
{
	return x>y?x:y;
}
bool dfs(int u)
{
	int i;
	for(i=head[u];i;i=nxt[i])
	{
		int v=adj[i];
		if(!vis[v])
		{
			vis[v]=3-vis[u];
			num[vis[v]]++;
			dfs(v);
		}
		else
		{
			if(vis[v]==vis[u])
				return false;
		}
	}
	return true;
}
int main()
{
	int n,m,i,j,x,y;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)	
	{
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	int ans=0;
	for(i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			vis[i]=1;
			num[1]=1;num[2]=0;
			if(!dfs(i))
			{
				printf("No\n");
				return 0;
			}
			ans+=mx(num[1],num[2]);
		}
	}
	printf("Yes\n%d\n",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值