首页 > 技术文章 > Just Oj 2017C语言程序设计竞赛高级组E: DATE ALIVE(二分匹配)

aeipyuan 2018-11-27 21:52 原文

 

 E: DATE ALIVE

时间限制: 1 s      内存限制: 128 MB     

提交 我的状态

题目描述

五河士道家里的精灵越来越多了,而每一个精灵都想和他有一个约会。然而五河士道却只有一个,无奈之下只能使出分身帮自己解围。

不过并不是所有的精灵都同意这样做,有些精灵不愿意和士道分身进行约会,也有部分精灵同时选择同一个分身进行约会。

假设有N个分身,精灵的数量为M,可能的约会组合有K组。

设N=3,M=5,K=5,可能的组合为1-1,1-3,2-4,3-4,3-5(如下图),为了避免冲突,我们最多可以选择1-1,2-4,3-5一共三种组合(或者是1-3,2-4,3-5)

那么请设计一个程序判断每一次可能的组队最多能确定多少队伍?最后,让我们的约会开始吧~

 

 

 

输入

输入N,M,K

N,M,K为正整数

1<=N<=500

1<=M<=500

接下来K行,输入u,v,表示uv之间愿意组队

u在N的范围内,v在M的范围内

输出

输出最大组队数目

样例输入

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

样例输出

3

题意:求最多可以匹配多少个道士;
分析:可以用匈牙利算法解决:枚举道士,找出匹配的精灵,若该精灵已经匹配,则判断是否可以让原配换一个精灵;
 

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
bool link[505][505];//判断两结点是否连接
bool used[505];//是否被访问过
int fa[505];//所配道士
int m;
bool find(int x)
{
	for(int i=1;i<=m;i++){
		if(link[x][i]&&!used[i]){
			used[i]=1;
			if(!fa[i]||find(fa[i])){//i无原配或者原配可以让出i换一个精灵
				fa[i]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int n,k;
	 scanf("%d%d%d", &n,&m,&k);
	 while(k--){
		 int x,y;
		 scanf("%d%d",&x,&y);
		 link[x][y]=1;//两点可以连接
	 }
	 int cnt=0;
	 for(int i=1;i<=n;i++){
		 memset(used,0,sizeof(used));//好几次忘了这个
		 if(find(i))
		 	cnt++;
	 }
	 printf("%d\n",cnt);
	 return 0;
}

 

推荐阅读