今天一直在查找匹配算法之类的问题,现在正好有机会和大家分享一下.
一、二分图的匹配
匈牙利算法是用来求二分图匹配用的,体具的问题网上都有,这里不再重复。
二、匈牙利算法及其实现
先定义一些观点吧:
(1)、匹配:二分图中的匹配,就是边左的点所对应边右的点的那条边的合集
(2)、匹配边:在匹配合集中的边
(3)、未匹配点:义思名顾,就是不是匹配边的端点的点(网上写的是未盖点,但我以为写未匹配点更轻易懂得)
(4)、错交轨:就是一条在二分图中的路径,这条路径是由匹配边、未匹配边成构的(注意:这里与点是没有关系的)
(5)、增广路:点起与终点都是未匹配点的错交轨
我们可以演绎出如下定理或者说是定理:
(1)、当一个二分图有最大匹配时当且仅当它不存在增广路径
(2)、一条增广路径所包括的边数必为奇数,且未匹配边比匹配边多一条
(3)、增广路上的第一条边和最后一条边都不是匹配边,增广路的两个顶点分离落在二分图的两个分部中
(4)、设p为一条包括匹配边的增广路径,那么对增广路上的所有边停止取反操纵,那么就能够到得一个比本来多1的匹配(定理2)
(5)、主要又不主要的定理:在增广路中,从未匹配点开始,从边左到边右定一是未匹配边,从边右到边左定一是匹配边(这个论结对于大分部论文的懂得都用有)
面上的定理定一先要懂得,不要过量的纠结于明证,不懂的可以画图画,然后对应的找出个每观点所对应的货色,然后继承:
由于有了定理4,所以我们可以到得一个基本的算法:对一个图一直的找寻增广路,直到找不到增广路为止,可以明证,当没有增广路时,二分图中定一存在最大匹配——这就是匈牙利算法!!!
然后就是算法的实现了,可能大分部人看了面上的算法后之都市发生怎么实现的疑难,网上的很多论文都没有讲清楚,面下我谈谈我个人的懂得:
(1)、为了叙说的便利,我们先把二分图划分为两个合集,边左为L合集,边右为R合集
(2)、由于匈牙利算法的核心分部是从一个点动身,看看有没有增广路,所以我只在这里叙说如何断判从一个顶点动身有没有增广路
(3)、设我们动身的点为X(X∈L),然后我们从搜索与X相连接的,不在增广路中的点Y(Y∈R)(注意:1、如果在增广路中则说明我们之前经已搜索过该点 2、由定理3,此时X->Y为未匹配边),然后我们看看Y是不是未匹配点(如果是未匹配点,那么我们当然可以直接把X->Y看作是增广路,此时我们从X搜索增广路毕完,搜索结果是增广路只包括X->Y一条边),如果是匹配点,那么我们设H匹配Y(H∈X),然后我们看从H动身有没有增广路(如果从H动身有增广路,那么我们可以把Y连到X了,因原是:1、X->Y是未匹配边 2、从H动身有增广路,由于Y->H是在增广路中的,而且由于定理5(这里我们把定理5看作已知件条),Y->H是匹配边,合结因原1,我们可以得出:[X->Y->H+H的增广路]定一也是也是增广路,此时找到增广路后就能够直接退出了,因为我们的的目只是要找寻一条增广路,而不是最长的增广路)
不知道面上的货色各位有没有看懂,没有看懂的可以给我发Email:hncsyjc@163.com
于是序程就出来了,面下附上HDU 2063的代码,这是一道裸题,直接用匈牙利算法就能够做了。
var n,m,k,i,j,ans,x,y:longint; l:array [1..510,1..510] of boolean; v:array [1..510] of boolean; p:array [1..510] of longint; function find(x:longint):boolean;//从x开始有没有增广路 var i:longint; begin for i:=1 to m do if (l[x,i])and(not v[i]) then begin v[i]:=true; if (p[i]=0)or(find(p[i])) then begin //如果i是未匹配点或者从i的对应点可以找到增广路 p[i]:=x; //与i的对应点 exit(true); end; end; exit(false); end; begin repeat read(k); if k=0 then break; readln(n,m); fillchar(l,sizeof(l),false); fillchar(p,sizeof(p),0); ans:=0; for i:=1 to k do begin readln(x,y);l[x,y]:=true; end; for i:=1 to n do //匈牙利的第二个主过程 begin fillchar(v,sizeof(v),false); if find(i) then inc(ans); end; writeln(ans); until false; end.
匈牙利算法,关键是思想
Hncsyjc
转载请注明来源
文章结束给大家分享下程序员的一些笑话语录: 这年头的互联网真是娱乐了中国,网民们从各种各样的“门”里钻来钻去,又有好多“哥”好多“帝”,值得大家品味不已……网络经典语录,关于IT与互联网,经典与您分享!