二分图最大匹配 - 匈牙利算法

来源:互联网 发布:新浪天气api接口 json 编辑:程序博客网 时间:2024/05/19 19:58

问题描述:

 X集合(编号1~m),Y集合(编号m+1~n)。n,m<100. 给出若干组合(x, y)(相当于映射x->y),问最都能同时有几个组合(分配)。

 

分析:

题目可能简化描述得不太好,这显然是一个二分图最大匹配的问题。(二分图)

可以用匈牙利算法,或者网络流来求解。这里介绍匈牙利算法。

匈牙利算法的核心就是找增广路。不断找增广路,然后更新现有匹配M(M可以看成是X->Y的一个特殊的映射关系),每次更新,都能使匹配数增加一。当找不到增广路时,M就是最大的匹配。

 

算法具体流程:

 

①记X上点为u,Y上点为v。记f[v] 为u->v的映射对应的u,即v的对应点,f[v]=u。(初始清零)记vis[u]为本次寻找增广路,点u是否访问过。

dfs(u)表示当前从点u出发有没有增广路,若有返回1,否则为0.

②遍历X集合,(u=1~m),每次遍历vis[]清零,dfs(u),若有找到增广路(即dfs(u)=1),则匹配数加1。最后的匹配数即为最大。

③dfs中, 从u出发找v(邻接表存图),

I.若v本次未访问过(!!),即vis[v]=0。

1)若v为未盖点,即f[v]=0(尚无对应点),(说明增广路找到了,是以v为结尾的)。

2)若dfs(f[v])=1,即f[v]≠0,v是盖点,f[v]是v在当前匹配M中对应的u' (联系增广路的定义,虚实交错)。则dfs(u')=1,同样说明增广路找到。v在这条增广路中。

所以以上两个条件是并列的,或( || )关系。

于是对M和这条增广路进行取反。令f[v]=u,(更新了M),return 1;(找到,回溯).

3)没找到,遍历u的下一个邻接点v。

II.若vis!=0; 不处理。

 

其实这个算法我还是有些地方不是很明白。

代码:

 

 

原创粉丝点击