题解:P3386 【模板】二分图最大匹配
langmouren · · 题解
网络流二分图最大匹配
前言
这篇题解使用了 Dinic 算法解决了二分图最大匹配问题,但是和其他题解不同的是,我们使用了神秘的 vector。
本片题解会浅略讲解 vector 如何使用在网络流上,以及网络流如何解决二分图最大匹配问题。
在阅读本题解之前,你需要了解网络最大流。
vector 版网络流
vector 的难点是,其相对于链式前向星难以找到反边,所以我们应该为其找到一个
我们约定 vector 数组 vector<Node> v[MN]。
可以发现,对于两个点 v[b][v[a].id] 就是
所以,我们可以写出 vector 加边的代码:
void add(int a,int b,int k){
int sza=v[a].size(),szb=v[b].size();
v[a].push_back({b,k,szb});
v[b].push_back({a,0,sza});
}
同时,我们也知道了,vector 的结构体中需要存储连向的边、流量、
网络流解决二分图最大匹配
我们设超级原点
将所有左部点和
需要注意,右部点应该加上一定偏移来保证其编号不与左部点重合,例如在本题中,左部点共有
最后从
为什么这样建边是正确的
因为在网络流中有反边的存在,所以我们只需要从左部点连向右部点,它就会自然地进行类似匈牙利算法的不断向下 DFS 的操作。
而连接超级原点和超级汇点是为了防止有遗漏,匈牙利算法就是因为无法解决遗漏问题而不得不多次进行 DFS。
代码
请见洛谷剪切板。
如不能访问上面连接,也可以访问洛谷保存站。