二分匹配算法(匈牙利算法初识)


今天刚接触的二分匹配算法,在翻阅了几篇大佬的博客后觉得理解的还可以,于是便解决上面这个简单的问题。主要用到的是匈牙利算法,看到很多的博主都提到了这个算法,而且都做了大量的解释,但作为一个新人我就不做什么解释了,毕竟自己理解的也就一般般,但我还是想要简单的解释一些,毕竟也是一上午的脑细胞牺牲换来的成果;

简单来说呢,就是一个大型的相亲现场,一个女孩可以看上不定数量的男生(当然是彼此的),找到一种组合方式,使找到对象的人数最多,找到有多少组成功相亲;因为一个人可能看上许多个对象,那么就要一个一个的遍历了;遍历时先给1号找到一个对象即可,当然找的时候需要他们两个相互之间有关系,毕竟不能硬塞不是(大笑)。当第一个女生找到对象后给第二个女生找个对象,如果第二个女生找到的和第一个女生找到的同一个人的话。那么一号女生当然是要让一下了,于是一号女生看向剩余的男生,如果还有另一个有关系的男生的话,那那她就会把当前的这个男生让给二号女生了,自己去找另一个有兴趣的男生。但是如果一号女生找不到心仪的男生了,或者自己心仪的男生都被自己抛弃过了,那么她就不会将自己最后的选择让出去了。那么就轮到二号女生去剩下的人中去寻找自己的目标了,毕竟人家不让自己也不能明抢不是。按以上步骤依次类推直到最后一个女生找到目标,或者没有目标可以选择,那么此次相亲就结束了。

以上就是匈牙利算发的解释了,刚接触可能会理解不到位,欢迎指出问题。

接下来是刚刚AC的一个题和代码,算是一上午的劳动成果了;


                                               过山车

题目来自:hud(2063)

RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?

Input

输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。

Output

对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。

Sample Input

6 3 3
1 1
1 2
1 3
2 1
2 3
3 1
0

Sample Output

3

AC代码

#include<stdio.h>
#include<string.h>
int match[1001];
int vis[1001];
int map[505][505];
int m;
int find(int x)
{
	int i,j,k;
//	printf("%**");
	for(i=1;i<=m;i++)
	{
	 //   printf("%d$%d\n",i,x);
		if(vis[i]==0 && map[i][x])
		{
			vis[i]=1;
			
			if(match[i]==-1 || find(match[i]))
			{
				match[i]=x;
				return 1;
			}
		}
	}
	//printf("%**");
	return 0;
}
int main()
{
	int n,i,j,k,a,b,sum;
	while(scanf("%d",&k),k!=0)
	{
		sum=0;
		scanf("%d%d",&m,&n);
		memset(map,0,sizeof(map));
		memset(match,-1,sizeof(match));
		for(i=0;i<k;i++)
		{
			scanf("%d%d",&a,&b);
			map[a][b]=1;
		}
		for(i=1;i<=n;i++)
		{
			memset(vis,0,sizeof(vis));
			if(find(i))
			sum++;
		}
		printf("%d\n",sum);
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/weixin_44584292/article/details/99627466