带花树
带花树是一种求解一般图最大匹配的算法。时间复杂度上限 O ( n 3 ) O(n^3) O(n3)。
首先推荐一篇很好理解的博客。
一般图相较于二分图就是图上多了奇环,而“花”指的就是图中的奇环。对于奇环的匹配:首先在环内尽可能地匹配显然是最优的,若环上有 2 k + 1 2k+1 2k+1个点,则环内可以用 k k k条边匹配任意 2 k 2k 2k个点,剩下一个未匹配的点可以向外匹配,这个未匹配点是根据需要回溯时才确定的,所以将奇环缩点,用并查集维护是否在同一个“花”内。
具体来说,我们每次选择一个未匹配点 b f s bfs bfs进行增广(将该点标记为 S S S),并将所有访问到的点标记为 S S S或 T T T(出发点标记为 S S S)。为了回溯连边还需要用到 p r e pre pre数组,对于每个标记为 T T T的点 i i i, p r e i pre_i prei表示当前 b f s bfs bfs中 i i i点第一次是被哪个结点访问到的。
一颗 b f s bfs bfs树形如:
其中起点为 s s s,黑点标记为 S S S,红点标记为 T T T。 S , T S,T S,T标记则相当于二分图匹配中的出度和入度一样。
如同二分图匹配,每次只增广 S S S标记点,将需要增广的点逐个压入队列(一开始队列中只有起点 S S S)依次处理。
如果 d f s dfs dfs的话不能之间判断增广点的类型,甚至可能增广到一个首尾都是自己的奇环,所以 b f s bfs bfs做的实际上是一个给点定型的操作,缩点后转成二分图。
模拟一下从当前点 x x x向外扩展到 v v v的情况: