二分匹配是两个集合之间的连接问题,给出一个集合,集合中的每个元素在另一个结合里面有与之对应的关系,根据他们之间的关系求解问题。其中集合中的元素都有且只有另一个集合一个元素在其中与之对应。这和数学中的函数关系相同。
二部图:
是图论中的一种特殊图,是二分匹配的模型图。简单来说就好像一个男生群体和一个女生群体,两个群体之间互相寻找人生另一半,当然 为保证一生生活幸福,当然要专一,一生只爱一个,幸福才能到来。因此这两个群体中每个人都会都一个伴侣。也就构成了图的两部分,每个元素有且只有一个连线与另一个元素对应。
匈牙利算法:(借鉴他人图片写下本人对匈牙利算法理解)
不得不说,路飞考虑到兄弟们和自己都有一身本领,但身边却没有伴侣相配,这与自古英雄爱美人不合啊。这天路飞把大家召集起来,希望自己兄弟身边都有人照顾,找了几个现代明星当候选,看能不能找到自己和兄弟满意的另一半,当然还要得到另一半同意。几人相互了解之后都把自己意向说了出来,剩下的就是考虑每个人都幸福问题了。
1--------------------------------------------------------------
开始当然是草帽船长选择了,看到还有其他兄弟,路飞也没挑,直接指向了第一个,算是找到了。
现在路飞一号和女生一号连接。其他待定。
2--------------------------------------------------------------
船长已经选好了,该船员了,索隆三刀大神正睡觉,被叫醒了,迷迷糊糊的指向了一个。他选了女生的二号
现在路飞船长和女生一号相连,索隆和女生二号相连。其他待定。
3---------------------------------------------------
轮到长鼻子了,他比较害羞,说出自己的意愿时间,看到自己看中都有人选过了,这可如何是好,也没说什么,船长虽然是傻了点,脑子好使,但对待兄弟确实很好的,看出了长鼻子的想法,既然长鼻子对女生一号有想法,那我就让给他吧,而索隆也看出来船长要干嘛,于是想,船长在让出来,那岂不是以后没人照顾他了,脑子不好使,没人照顾,说不定以后又捅啥篓子了,我也让出来吧。于是,索隆找到了女生3号,船长找到了女生2号,而长鼻子就找到了女生一号。
目前草帽船长路飞和女生2号连接,索隆和女生3号相连,长鼻子和女生1号相连,其他待定。
4-------------------------------------------------
现在就剩下整个海贼团最花心的香吉士了,这个花心大罗卜算是出了名的,看见美女就想往上扑,虽然长的帅,带现在每人理他,毕竟现在是找用情专一的人,女生都不愿意,除了女生三号看上他的脸,毕竟是海贼团里的帅哥,而现在女生三号和索隆已经定了,索隆和这花心大罗卜向来对着干,并且索隆要是再让出来 ,他就一个人了,让他一个路痴出去跑,指不定有跑丢了,因此索隆不会让出来。
目前草帽船长路飞和女生2号连接,索隆和女生3号相连,长鼻子和女生1号相连,而香吉士,长的帅有屁用,花心大箩卜向来没人看好。
--------------------------------------------------------
借鉴图片讲故事,借此讲解匈牙利算法,希望对大家有所帮助。当然这只是一个匈牙利算法的过程,具体实现还是要仔细看模板,自己理解代码。下面是一个模板水题。
具体的思路可以这样理解,首先开始在一个集合1中的元素按编号和集合2中的元素依次进行尝试匹配,当这个集合1中的当前元素在集合2中没有与之匹配的元素时间,回溯到之前的元素,把之前集合1中匹配过的元素拆开,和集合二中还未匹配的元素进行匹配,直到最后所有的元素都有匹配对象或者不能继续进行匹配时间结束
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;
}