求一个二分图的最大匹配,朴实的匈牙利算法的复杂度为O (VE),优点是代码量很少,而且顶点数目在1000以内的时候表现不错。
bool dfs(int u,int tot){
for(int i = head[u];i != -1; i = e[i].nxt){
int v= e[i].v;
if(vis[v] == tot) continue;
vis[v] = tot;
if(con[v] == -1 || dfs(con[v],tot)) {
con[u] = v;con[v] = u;return true;
}
}return false;
}
但是当这个复杂度不足以解决问题的时候,比如说遇到这题的时候
HDU2389
就需要更优秀的算法来求最大匹配,于是就强制学习了一下HK算法
网上看了一些资料之后大多是描述算法步骤而证明比较简略,而在理解步骤之后发现HK算法可以看成是在匈牙利算法之上的优化,在原来的基础上加了一个bfs,dfs函数稍微改动一点。
问:这个bfs是干嘛的?
预先找到多条路径最短的增广路,然后匈牙利算法就沿着bfs找的路径去找增广路。
bfs具体步骤:
设二分图为X和Y两部分
- 把X中所有没匹配的点加入队列
- 每次出来一个点u,对于它连的Y中的每个点v,如果v没访问过且没匹配过,找到增广路,否则把v的匹配点压入队列
bfs的时候顺便记录一下每个点在bfs中的层次