二分图最大匹配
Views: --
二分图 的顶点分成互不相交的左右两部分,每条边都连接一左一右。匹配 要求每个顶点至多关联一条匹配边;最大匹配要让边数 尽可能大。
1. 为什么直接挑空闲边会失败
某个左点可能有多个候选右点,而另一个左点只有唯一候选。如果先随意占用唯一候选,后者就无法匹配。局部选择需要允许“反悔”和重新安排。
2. 交替路与增广路
相对于当前匹配 :
- 交替路上的边在“非匹配、匹配、非匹配……”之间交替;
- 增广路是一条以两个未匹配顶点为端点的交替路。
沿增广路翻转边的状态:非匹配边加入 ,匹配边移出 。由于增广路比匹配边多一条,匹配大小恰好增加 1。
3. 最大性判据
Berge 定理:匹配 是最大匹配,当且仅当不存在相对于 的增广路。
一方面,有增广路就能增大匹配;另一方面,若存在更大匹配 ,考察对称差 ,其中必有一个交替路径分量在 中多一条边,于是构成 的增广路。
4. DFS 增广的匈牙利算法
依次尝试让每个左侧顶点找到增广路:
augment(u):
for each v in Adj[u]:
if v was tried in this search: continue
mark v tried
if matchRight[v] is empty
or augment(matchRight[v]):
matchRight[v] = u
return true
return false
for each u in L:
clear tried marks
if augment(u): answer++
若右点 已匹配,就递归尝试给原来的左点换一个位置;成功后把 让给当前 。递归调用正是在寻找交替增广路。
5. 为什么每轮要重置访问标记
tried[v] 只表示“当前这次增广搜索已经尝试过右点 ”。换一个新的起点后,匹配结构可能已经改变,必须重新搜索。若全程只标一次,会漏掉合法增广路。
6. 复杂度
每个左点至多发起一次 DFS,一次搜索最坏检查 条边,总复杂度常写为
更大的图可用 Hopcroft–Karp,在每轮 BFS 中同时寻找一批最短增广路,达到 。
7. 与最大流的关系
建立源点 到每个左点容量 1 的边、原二分边容量 1、每个右点到汇点 容量 1 的边。整数最大流的每个单位流对应一条匹配边,因此最大流值等于最大匹配数。
这也解释了“每个顶点至多匹配一次”如何被容量约束表达。
8. 二分图判定与匹配不是一回事
先用 BFS/DFS 二染色可以判断一般无向图是否二分。只有确认二分后,才能把两个颜色集合当作 与 运行上述算法。
9. 常见扩展
- 完美匹配:每个顶点都被匹配;
- 加权匹配:优化总权值,不能用普通 DFS 增广直接解决;
- 二分图最小点覆盖:由 Kőnig 定理,其大小等于最大匹配大小;
- 指派问题:通常要求完美匹配并最小化总成本,对应带权匈牙利算法。
课程语境中的“匈牙利算法”有时指 DFS 增广,有时指带权指派算法,答题前要按题目定义确认。