二分匹配 匈牙利算法

           二分匹配是两个集合之间的连接问题,给出一个集合,集合中的每个元素在另一个结合里面有与之对应的关系,根据他们之间的关系求解问题。其中集合中的元素都有且只有另一个集合一个元素在其中与之对应。这和数学中的函数关系相同。

 二部图:

       是图论中的一种特殊图,是二分匹配的模型图。简单来说就好像一个男生群体和一个女生群体,两个群体之间互相寻找人生另一半,当然 为保证一生生活幸福,当然要专一,一生只爱一个,幸福才能到来。因此这两个群体中每个人都会都一个伴侣。也就构成了图的两部分,每个元素有且只有一个连线与另一个元素对应。

        匈牙利算法:(借鉴他人图片写下本人对匈牙利算法理解)

        不得不说,路飞考虑到兄弟们和自己都有一身本领,但身边却没有伴侣相配,这与自古英雄爱美人不合啊。这天路飞把大家召集起来,希望自己兄弟身边都有人照顾,找了几个现代明星当候选,看能不能找到自己和兄弟满意的另一半,当然还要得到另一半同意。几人相互了解之后都把自己意向说了出来,剩下的就是考虑每个人都幸福问题了。

       

    1--------------------------------------------------------------

     

      开始当然是草帽船长选择了,看到还有其他兄弟,路飞也没挑,直接指向了第一个,算是找到了。

      现在路飞一号和女生一号连接。其他待定。

    2--------------------------------------------------------------

      

      船长已经选好了,该船员了,索隆三刀大神正睡觉,被叫醒了,迷迷糊糊的指向了一个。他选了女生的二号

      现在路飞船长和女生一号相连,索隆和女生二号相连。其他待定。

    3---------------------------------------------------

     

     轮到长鼻子了,他比较害羞,说出自己的意愿时间,看到自己看中都有人选过了,这可如何是好,也没说什么,船长虽然是傻了点,脑子好使,但对待兄弟确实很好的,看出了长鼻子的想法,既然长鼻子对女生一号有想法,那我就让给他吧,而索隆也看出来船长要干嘛,于是想,船长在让出来,那岂不是以后没人照顾他了,脑子不好使,没人照顾,说不定以后又捅啥篓子了,我也让出来吧。于是,索隆找到了女生3号,船长找到了女生2号,而长鼻子就找到了女生一号。

    目前草帽船长路飞和女生2号连接,索隆和女生3号相连,长鼻子和女生1号相连,其他待定。

   4-------------------------------------------------

       

       现在就剩下整个海贼团最花心的香吉士了,这个花心大罗卜算是出了名的,看见美女就想往上扑,虽然长的帅,带现在每人理他,毕竟现在是找用情专一的人,女生都不愿意,除了女生三号看上他的脸,毕竟是海贼团里的帅哥,而现在女生三号和索隆已经定了,索隆和这花心大罗卜向来对着干,并且索隆要是再让出来  ,他就一个人了,让他一个路痴出去跑,指不定有跑丢了,因此索隆不会让出来。

      目前草帽船长路飞和女生2号连接,索隆和女生3号相连,长鼻子和女生1号相连,而香吉士,长的帅有屁用,花心大箩卜向来没人看好。

     --------------------------------------------------------

     借鉴图片讲故事,借此讲解匈牙利算法,希望对大家有所帮助。当然这只是一个匈牙利算法的过程,具体实现还是要仔细看模板,自己理解代码。下面是一个模板水题。

     具体的思路可以这样理解,首先开始在一个集合1中的元素按编号和集合2中的元素依次进行尝试匹配,当这个集合1中的当前元素在集合2中没有与之匹配的元素时间,回溯到之前的元素,把之前集合1中匹配过的元素拆开,和集合二中还未匹配的元素进行匹配,直到最后所有的元素都有匹配对象或者不能继续进行匹配时间结束

    

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

           模板水题;

    代码:

     

#include
#include
int a[510][510];
int g[510],u[510];
int m,n;
int fun(int x)
{
   int i;
   for(i=1;i<=n;i++)	
   {
   	   if(a[x][i]!=0&&u[i]==0)
   	   {
   	   	  u[i]=1;
   	   	  if(g[i]==0||fun(g[i])!=0)
   	   	  {
   	   	  	  g[i]=x;
   	   	  	  return 1;
				}
		  }
   }
   return 0;
} 
int main()
{
	int i,j,k,x,y;
	while(scanf("%d",&k),k!=0)
	{
		scanf("%d%d",&m,&n);
		memset(a,0,sizeof(a));
		memset(g,0,sizeof(g));
		for(i=0;iscanf("%d%d",&x,&y);
		   a[x][y]=1;
		}
		j=0;
		for(i=1;i<=m;i++)
		{
			memset(u,0,sizeof(u));
			if(fun(i))
			  j++;  
		}
		printf("%d\n",j);
	}
	return 0;
}

    

  

    

你可能感兴趣的:(二分匹配)