本文主要是介绍HDU2063-过山车(二分匹配 +匈牙利算法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。
6 3 3 1 1 1 2 1 3 2 1 2 3 3 1 0
3
思路:
就是通过匈牙利算法模板来求解问题,下面简单介绍一下匈牙利算法:
匈牙利算法的实际是网络流思想,核心是寻找增广路。
下面简单描述一下算法:
以下转自:点击打开链接
通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(-_-||暂时不考虑特殊的性取向),如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在让我们无视掉所有的单相思(好忧伤的感觉),你拥有的大概就是下面这样一张关系图,每一条连线都表示互有好感。
本着救人一命,胜造七级浮屠的原则,你想要尽可能地撮合更多的情侣,匈牙利算法的工作模式会教你这样做:
===============================================================================
一: 先试着给1号男生找妹子,发现第一个和他相连的1号女生还名花无主,got it,连上一条蓝线
===============================================================================
二:接着给2号男生找妹子,发现第一个和他相连的2号女生名花无主,got it
===============================================================================
三:接下来是3号男生,很遗憾1号女生已经有主了,怎么办呢?
我们试着给之前1号女生匹配的男生(也就是1号男生)另外分配一个妹子。
(黄色表示这条边被临时拆掉)
与1号男生相连的第二个女生是2号女生,但是2号女生也有主了,怎么办呢?我们再试着给2号女生的原配()重新找个妹子(注意这个步骤和上面是一样的,这是一个递归的过程)
此时发现2号男生还能找到3号女生,那么之前的问题迎刃而解了,回溯回去
2号男生可以找3号妹子~~~ 1号男生可以找2号妹子了~~~ 3号男生可以找1号妹子
所以第三步最后的结果就是:
===============================================================================
四: 接下来是4号男生,很遗憾,按照第三步的节奏我们没法给4号男生腾出来一个妹子,我们实在是无能为力了……香吉士同学走好。
===============================================================================
其原则大概是:有机会上,没机会创造机会也要上
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
int line[510][510],boy[510],used[510];
int n,m;
int Find(int x)
{int i,j;for(i=1;i<=m;i++)//遍历所有被选者 {if(line[x][i]==1&&used[i]==0){//如果 x对i有好感且在这一个递归选取阶段没有被选取(哪怕是暂时选取,新的递归可能会换) used[i]=1;//标记被选取 if(boy[i]==0||Find(boy[i]))//如果被选者没有归属或他的归属着可以调换(他的归属者可以选择其它被选者) {boy[i]=x;//将归属定为 x return 1;}}}return 0;
}
int main()
{int i,j,k,x,y,sum;while(scanf("%d %d %d",&k,&n,&m),k!=0){memset(line,0,sizeof(line));memset(boy,0,sizeof(boy));memset(used,0,sizeof(used));for(i=0;i<k;i++){scanf("%d %d",&x,&y);line[x][y]=1;//表示 x希望与 y有关系 } sum=0;//记录能撮合的情侣对数 for(i=1;i<=n;i++) {memset(used,0,sizeof(used));//每次都要清 0 if(Find(i)) sum++;//找到一对就记录 }printf("%d\n",sum);}return 0;
}
这篇关于HDU2063-过山车(二分匹配 +匈牙利算法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!