一般图最大匹配
一般图最大匹配 比较摸,不是很有学带花树的动力,网上冲浪冲到了随机算法: 首先如果给定的图没有环,直接做类似二分图匹配的匈牙利肯定是对的。如果图中的环都是偶数,增广一下也不会有问题。(二分图就是偶环) 但是如果图中有奇环,可以发现绕环增广会挂掉。。 举个例子,一个大小为$3$的环,选了其中一条边。把环上所有边取反,就冲突了。 那么怎么做呢?可以发现如果可以钦定增广边的时候的顺序,那么其实直接每次把匹配边找出来就行了。 这个顺序不是很清楚,但是我们可以进行多个轮,每次随机一下出边再匹配,随机次数足够多的话有很大的概率是对的。 这里是Hack方法 对随机法进行一些优化:不采用开始前随机,而采用在DFS内部每次随机。每一轮不清空匹配数组。用时间戳优化复杂度。事实证明这样甚至可以过掉UOJ上的Hack数据..
1 |
|
Update:带花树(真香 随机匹配其实挺好的,就是跑的慢。所以还是需要稳定优秀的Blossom Algorithm。 首先想一下二分图最大匹配是怎么玩的:
- 定义增广路。即未匹配边和匹配边交替出现的一条路径。增广路取反后答案+1。
- 增广路定理。找不到增广路的时候就是最大匹配。
这两个并不是定义在二分图上的。所以一般图匹配的步骤也是这样的:
- 枚举每个点
- 找这个点出发的增广路并更新
- 枚举下一个点
所以问题就变成了找一个点出发的增广路。考虑对图染色。从一个黑点出发,把路径染成一黑一白的样子。那么图就有三种点:黑,白,未染色。
- 考虑搜索路径。如果当前在黑点,并且搜到了一个白点,那么可以直接忽略这个点。
- 如果搜到了一个未染色点,考虑这个点是不是匹配点。如果不是匹配点,说明找到了增广路。
- 如果是匹配点,那么钦定它是白色,并移动到它匹配的另一个点上,染黑色,继续。
- 如果图中存在奇环,会遇到两个黑点相邻的情况。考虑环上有一条到外面的路,发现无论起点是什么颜色,都可以走出去。也就是说环上每个点都应该是黑点。
定义一个$2k+1$大小,$k$条匹配边的奇环为花。花中的未匹配点为花托。因为整个花都是黑点,定义缩花操作为把花缩成一个点。因为每次至少缩两个点,操作次数是线性的。 思路就是这样的,下面说一下算法细节:
- BFS遍历图,染色
- 找到奇环时,找到两点的LCA,并缩花
- 因为有一个遍历的过程,维护pre[],表示返回时要返回到哪里
- 不执行实际的缩花操作,用并查集维护
之后看代码吧
1 |
|