一般图最大权匹配

图论 / 图匹配

本地源文件:docs/graph__graph-matching__general-weight-match.md

一般图最大权匹配

本页从一般图最大权完美匹配到一般图最大权匹配(最大权匹配可以通过增加零边变成最大权完美匹配).

预备知识

花(blossom)

一般图匹配和二分图匹配不同的是,图可能存在奇环.可以将偶环视为二分图.

带花树算法(Blossom Algorithm)的处理方式时是遇到奇环就把它缩成一个 花(Blossom) ,并把花中所有的点设为偶点.既然花上的点都可以成为偶点,那么可以把整个花直接缩成一个偶点.注意,一个花可以包含其它花.

这也可以变成线性规划和对偶问题,但是要对花进行一些处理.

顶标(vertex labeling)和等边(Equality Edge)

定义 𝑧𝑢zu 是点 𝑢u 的顶标(vertex labeling),与 𝐾𝑀KM 算法中定义的顶标含义相同.定义边 𝑒(𝑢,𝑣)e(u,v) 为 "等边" 当且仅当点 𝑢u 和点 𝑣v 的标号和等于边 𝑒e 的权值(𝑧𝑢 +𝑧𝑣 =𝑤(𝑒)zu+zv=w(e)),此时边的标号 𝑧𝑒 =𝑧𝑢 +𝑧𝑣 −𝑤(𝑒) =0ze=zu+zv−w(e)=0

一般图最大权完美匹配的线性规划

定义

因为一朵花最少有三个点,缩花后成为一个点.设 𝑂O 为大小为 ≥3≥3 奇数的集合的集合(包含所有花),𝛾(𝑆)γ(S) 表示 𝑆S 集合中的边.

设𝑆⊆𝑉𝛾(𝑆)={(𝑢,𝑣)∈𝐸:𝑢∈𝑆,𝑣∈𝑆}𝑂={𝐵⊆𝑉:|𝐵|是奇数且|𝐵|≥3}设S⊆Vγ(S)={(u,v)∈E:u∈S,v∈S}O={B⊆V:|B|是奇数且|B|≥3}

对偶问题

原问题 max∑𝑒∈𝐸𝑤(𝑒)𝑥𝑒限制:𝑥(𝛿(𝑢))=1:∀𝑢∈𝑉𝑥(𝛾(𝐵))≤⌊|𝐵|2⌋:∀𝐵∈𝑂𝑥𝑒≥0:∀𝑒∈𝐸max∑e∈Ew(e)xe限制:x(δ(u))=1:∀u∈Vx(γ(B))≤⌊|B|2⌋:∀B∈Oxe≥0:∀e∈E

然后通过原始对偶(Primal-Dual)将问题转换为对偶问题.

对偶问题 min∑𝑢∈𝑉𝑧𝑢+∑𝐵∈𝑂⌊|𝐵|2⌋𝑧𝐵限制:𝑧𝐵≥0:∀𝐵∈𝑂𝑧𝑒≥0:∀𝑒∈𝐸设𝑒=(𝑢,𝑣),这里𝑧𝑒=𝑧𝑢+𝑧𝑣−𝑤(𝑒)+∑𝐵∈𝑂𝑢,𝑣∈𝛾(𝐵)𝑧𝐵min∑u∈Vzu+∑B∈O⌊|B|2⌋zB限制:zB≥0:∀B∈Oze≥0:∀e∈E设e=(u,v),这里ze=zu+zv−w(e)+∑B∈Ou,v∈γ(B)zB

𝑥𝑒 =1xe=1 的边是匹配边,𝑥𝑒 =0xe=0 的边是非匹配边.和二分图一样,我们必须满足 𝑥𝑒 ∈{0,1} :∀𝑒 ∈𝐸xe∈{0,1}:∀e∈E.因此必须在最大权完美匹配的时候,让所有匹配边都是 等边 的.

和二分图不同的是,一般图多了 𝑧𝐵zB 要处理.下面考虑 𝑧𝐵zB 什么时候大于 00

可以看出,尽量使 𝑧𝐵 =0zB=0 是最好的做法,但在不得已时还是要让 𝑧𝐵 >0zB>0.在 𝑥(𝛾(𝐵)) =⌊|𝐵|2⌋且𝑥(𝛿(𝐵)) =1x(γ(B))=⌊|B|2⌋且x(δ(B))=1 时,让 𝑧𝐵 >0zB>0 即可.因为除了在这种情况下,𝑧𝐵 >0zB>0 是无意义的.

根据互补松弛条件,有以下的对应关系:

  • 对于选中的边 𝑒e,必有 𝑧𝑒 =0ze=0

𝑥𝑒>0⟶𝑧𝑒=0,∀𝑒∈𝐸xe>0⟶ze=0,∀e∈E

  • 对于选中的集合 _B_ ,𝑧𝐵 >0 ⟶𝑥(𝛾(𝐵)) =⌊|𝐵|2⌋zB>0⟶x(γ(B))=⌊|B|2⌋,即所有 𝑧𝐵 >0zB>0 的集合 𝐵B,都被选了集合大小一半的边,也即集合 𝐵B 是一朵花,选中花中的一条边进行增广.同时,我们加入一个条件:𝑥(𝛿(𝐵)) =1x(δ(B))=1,即只有花 𝐵B 向外连了一条边的时候,𝑧𝐵 >0zB>0 才是有意义的.

𝑧𝐵>0⟶𝑥(𝛾(𝐵))=⌊|𝐵|2⌋,𝑥(𝛿(𝐵))=1∀𝐵∈𝑂zB>0⟶x(γ(B))=⌊|B|2⌋,x(δ(B))=1∀B∈O

以「等边 」的概念,结合之前的带花树算法:用「等边」构成的增广路不断进行扩充,由于用来扩充的边全是「等边」,最后得到的最大权完美匹配仍然全是「等边」.

处理花的问题

当遇到花的时候,要将它缩成一个偶点.将花中所有点都设为偶点,并让它的 𝑧𝐵 =0zB=0

由于缩花后会把花保存起来,直到满足某些条件才会拆开,所以不能用之前的方法记录花.

如果没有特殊说明,之前提到的点,都包含缩花形成的偶点.

由于花也有可能缩成点被加入队列中,并且花的数量是不固定的,因此不能像之前一样枚举每个点来检查是否有增广路.因此,在进行广度优先搜索(BFS)时,必须将所有未匹配的点都放入队列中.

这样会同时产生很多棵交错树.

算法的四个步骤

这个算法可以分成四个步骤.

  1. GROW(等边):用 "等边" 构成交错树.
  2. AUGMENT(增广):找出增广路并扩充匹配.
  3. SHRINK(缩花):把花缩成一个点.
  4. EXPAND(展开):把花拆开.

general-weight-match-1

在 AUGMENT 阶段时,因为所有未匹配点都会在不同的交错树上,所以当增广时两棵交错树的偶点连在一起,就表示找到了一条增广路.

找不到等边扩充

和二分图一样,也会有找不到「等边」扩充的问题.这时就需要调整 vertex labeling.

调整 VERTEX LABELING

vertex labeling 仍要维持大于等于的性质,而且既有的「等边」不能被改变,还要让 𝑧𝐵zB 尽量的小.

定义符号 奇偶点

以 𝑢−u− 来表示 𝑢u 在交错树上为奇点. 以 𝑢+u+ 来表示 𝑢u 在交错树上为偶点. 以 𝑢∅u∅ 来表示 𝑢u 不在任何一棵交错树上. 之后所有提到的 𝐵B 预设都是花,并同时代表缩花之后的点. 花也可以有奇花偶花之分,因此也适用 𝐵+B+、𝐵−B−、𝐵∅B∅ 等符号.

设目前有 r 棵交错树 𝑇𝑖 =(𝑈𝑡𝑖,𝑉𝑡𝑖) :1 ≤𝑖 ≤𝑟Ti=(Uti,Vti):1≤i≤r,令

𝑑1=min({𝑧𝑒:𝑒=(𝑢+,𝑣∅)})𝑑2=min({𝑧𝑒:𝑒=(𝑢+,𝑣+), 𝑢+∈𝑇𝑖, 𝑣+∈𝑇𝑗, 𝑖≠𝑗})/2𝑑3=min({𝑧𝐵−:𝐵−∈𝑂})/2d1=min({ze:e=(u+,v∅)})d2=min({ze:e=(u+,v+), u+∈Ti, v+∈Tj, i≠j})/2d3=min({zB−:B−∈O})/2

注意这里 _B_ 是缩花之后的点,所以可以有奇偶性.

设 𝑑 =𝑚𝑖𝑛(𝑑1,𝑑2,𝑑3)d=min(d1,d2,d3),让

𝑧𝑢+−=𝑑𝑧𝑣−+=𝑑𝑧𝐵++=2𝑑𝑧𝐵−−=2𝑑zu+−=dzv−+=dzB++=2dzB−−=2d

如果出现 𝑧𝐵 =0(𝑑 =𝑑3)zB=0(d=d3),为了防止 𝑧𝐵 <0zB<0 的情况,所以要把这朵花拆了 (EXPAND). 拆花后只留下花里的交替路径,并把花里不在交替路径上的点设为未走访 (∅∅).

如此便制造了一条(以上)的等边,既有等边保持不动,并维持了 𝑧𝑒 ≥0 :∀𝑒 ∈𝐸ze≥0:∀e∈E 的性质,且最低限度增加了 𝑧𝐵zB,可以继续找增广路了.

一般图最大权匹配

以上求的是最大权完美匹配,求最大权匹配需要在 vertex labeling 额外增加一个限制:对于所有匹配点 𝑢u,𝑧𝑢 >0zu>0

开始时先设所有的 𝑧𝑢 =𝑚𝑎𝑥({𝑤(𝑒) :𝑒 ∈𝐸})/2zu=max({w(e):e∈E})/2

vertex labeling 为 00 的点最后将成为未匹配点.

参考代码

这里为了方便实现,使用边权乘 22 来计算 𝑧𝑒ze 的值,这样就不会出现浮点数误差了.

存储

---|---

下面是嵌套花的例子.

![general-weight-match-2](./images/general-weight-match-2.png)

其中 {6,5,8} ∈𝑏1,{𝑏1,4,3,2,11,10,9} ∈𝑏2{6,5,8}∈b1,{b1,4,3,2,11,10,9}∈b2![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7).存储为:

---|---

general-weight-match-3

---|---

---|---

general-weight-match-4

---|---

---|---

---|---

---|---

general-weight-match-5

如果使用 get_pr(b2,11)flower[b2] 会变成 {9,10,11,2,3,4,b1},并返回 2.

如果使用 get_pr(b2,2)flower[b2] 会变成 {9,b1,4,3,2,11,10},并返回 4.

---|---

增加一朵奇花

---|---

拆花

---|---

尝试增广一条等边

---|---

增广

---|---

主函数

---|---

初始化

很重要 使用前一定要初始化

---|---

## 复杂度分析

每朵花在一次 BFS 中只会被缩花或拆花一次.每次缩花或拆花的时间复杂度为 𝑂(|𝑉|)O(|V|)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7).最多总共有 𝑂(|𝑉|)O(|V|)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 朵花,所以花的处理花费 𝑂(|𝑉|2)O(|V|2)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 的时间.而 BFS 花费 𝑂(|𝑉| +|𝐸|)O(|V|+|E|)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 的时间复杂度.因此,找增广路花费 𝑂(|𝑉| +|𝐸|) +𝑂(|𝑉|2) =𝑂(|𝑉|2)O(|V|+|E|)+O(|V|2)=O(|V|2)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 的时间复杂度.

最多做 |𝑉||V|![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) 次 BFS.所以,总时间复杂度为 𝑂(|𝑉|3)O(|V|3)![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7).

## 习题

  * [UOJ #81. 一般图最大权匹配](https://uoj.ac/problem/81)

## 参考资料

  1. [Kolmogorov, Vladimir (2009), "Blossom V: A new implementation of a minimum cost perfect matching algorithm"](http://pub.ist.ac.at/~vnk/papers/BLOSSOM5.html)
  2. [从匈牙利算法到带权带花树——详解对偶问题在图匹配上的应用](https://www.luogu.com.cn/blog/potassium/solution-p6699)

* * *

>  __本页面最近更新: 2026/1/7 08:56:54,[更新历史](https://github.com/OI-wiki/OI-wiki/commits/master/docs/graph/graph-matching/general-weight-match.md)
>  __发现错误?想一起完善?[在 GitHub 上编辑此页!](https://oi-wiki.org/edit-landing/?ref=/graph/graph-matching/general-weight-match.md "edit.link.title")
>  __本页面贡献者:[Tiphereth-A](https://github.com/Tiphereth-A), [310552025atNYCU](https://github.com/310552025atNYCU), [Henry-ZHR](https://github.com/Henry-ZHR), [Xeonacid](https://github.com/Xeonacid), [yuhuoji](https://github.com/yuhuoji), [accelsao](https://github.com/accelsao), [c-forrest](https://github.com/c-forrest), [Enter-tainer](https://github.com/Enter-tainer)
>  __本页面的全部内容在**[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.zh) 和 [SATA](https://github.com/zTrix/sata-license)** 协议之条款下提供,附加条款亦可能应用