图的匹配

【概念】

都是无向图的概念

  • 支配集:一个点集,使得无向图中每个点要么是点集中的点,要么与点集相邻。

  • 独立集:一个点集,使得点集中任意两点不相邻。

以上两个在任意图中都是 NP 问题,也就是无法在多项式时间内求解的问题。

  • 点覆盖:一个点集,使得所有边都至少与点集中一个点相连。

结论:点覆盖的补集是独立集,独立集的补集也是点覆盖。

证明:若点覆盖的补集里存在一条边连接,说明这条边没覆盖;而所有边肯定不可能两端都属于独立集,所以独立集的补集一定覆盖了所有边。

推论:最小点覆盖 \(\iff\) 最大独立集。

  • 边覆盖:一个边集,使得所有点都有其中的邻边。(有孤立点则不存在边覆盖)

  • 匹配:一些不重合的点对,点对之间有边。(注意有的点可能没有被选)

  • 最大匹配:所有匹配中点对数量最多是多少

结论:最小边覆盖 = 最大匹配 \(k\;+ \;\)没有在匹配中选到的点的数量 \(n-2k\)

证明(感性):最小边覆盖每次尽量选连接两个新点的边,这就是找最大匹配。

由这个结论,我们只要求出最大匹配,就能求出最小边覆盖。

【支配集(没啥用)】

  • 图的结点分为支配集 \(U\) 与补集 \(V\),则 \(V\) 中点必然与 \(U\) 中某一个点相邻。
  1. 极小支配集:该支配集删除任意一个点,都不再是支配集。

  2. 最小支配集:点最少的支配集。

定理 \(\;\) \(U\) 为极小支配集,当且仅当对 \(U\) 中任意一个点 \(u\) 有如下条件,至少一个成立。

  1. \(u\) 不与 \(U\) 中其他点相邻。

  2. 存在 \(v\in V\),使 \(u\)\(v\) 的唯一 \(U\) 中邻点。

定理 \(\;\) 若无孤立点,极小支配集的补集也是支配集。

定理 \(\;\) 最小支配集大小 \(\le \dfrac{n}{2}\)

【匹配】

  • \(k\) 对相邻的结点,无公共点。求最大的 \(k\)

因为一般图匹配困难一些,先说二分图。

【二分图/二部图】

可以把 \(G=(V,E)\)\(V\) 分成两个点集 \(A,B\),使 \(E\) 中的边两端都分属 \(A,B\) 的图。

二分图判定:染色法。

【二分图最大匹配】

  • 无权,求最大匹配数。

法一:最大流 Dinic,\(O(m\sqrt n)\)

Dinic 的缺点是难写、不容易做拓展;优点是快。

\(S\) 向左半边连 \(1\) 边,右半边向 \(T\)\(1\) 边,左右之间的边流量都取 \(1\)。最大流就是最大匹配数。

为什么复杂度 \(O(m\sqrt n)\)?下面证明。(还没补)

  1. 先进行 \(O(\sqrt n)\) 轮找增广路。每轮 \(O(m)\)。共 \(O(m\sqrt n)\)

    为什么每次是 \(O(m)\)?这是因为边容量全是 \(1\),故每条边都只会在某增广路中贡献一次操作,所以总复杂度贡献是 \(O(m)\)

  2. 再在残余网络上找增广路,每次增加 \(1\) 流量。我们要说明距离找完所有增广路,最多还需要 \(O(\sqrt n)\),共 \(O(m\sqrt n)\)

    注意网络流里流了一条 \(A\rightarrow B\) 的边,就相当于匹配了这两个点。设我们此时 \(A,B\) 匹配了的边的集合是 \(P\),某最大匹配的匹配边集是 \(Q\)

    结论:\(P,Q\) 中的边形成了若干条锯齿状的路径。

    (不可能有点的度 \(\ge 3\),否则抽屉原理在 \(P\)\(Q\) 中存在一个点的度 \(\ge 2\),就不是匹配了)

    下证:剩余的增广路 \(\le \sqrt n\) 条。

    证明:因为已经做了 \(\sqrt n\) 轮 Dinic,所以剩下的增广路长度必然 \(\ge \sqrt n\) ……(待补)


法二:匈牙利算法,\(O(mn)\)。(不如 Dinic 呢 ~)

有一些概念:

  • 交替路径:轮换经过匹配边/非匹配边的路径。

  • 增广路:起止点都是非匹配点的交替路径。

依次访问 \(A\) 中点 \(i\),尝试对 \(i\) 找增广路。

  1. 成功找到增广路,则使增广路上所有边的匹配情况取反;

  2. 失败,则跳过。

bool srh(int x) {
    for (int j = 0; j < e[x].size(); j++)
        if (!vis[e[x][j]]) {
            vis[e[x][j]] = true;
            if (mc[e[x][j]] == -1 || srh(mc[e[x][j]])) {
                mc[e[x][j]] = x, tw[x] = e[x][j];
                return true;
            }
        }
    return false;
}

这里面 \(mc[x]\) 表示 \(x\in B\) 当前的匹配点,\(tw[x]\) 表示 \(x\in A\) 当前的匹配点。如果是 \(-1\) 表示当前没匹配。

Q:为什么 if 后面不用 vis[e[x][j]] = false

A:因为它现在就找不到增广路,以后更找不到增广路,可以直接 vis = true 避免重复访问。

\(srh(x)\) 表示从 \(x\in A\) 出发,判断是否存在一条交替路径,如果存在,返回 true 并全部取反;否则返回 false

匈牙利算法的缺点是慢;优点是好写、容易拓展。(比如我们只用匹配到中间的结果就行了,可以用匈牙利算法)

【最小点覆盖】

有一种求最小点覆盖的方法:

网络流,建立超源点 \(S\),向每个 \(i\in A\) 连容量 \(1\) 的边;建立超汇点 \(T\),每个 \(i\in B\)\(T\) 连容量为 \(1\) 的边;原本存在的边设置流量为 \(+\infty\)

求最小割就是答案。因为对于每一条 \(+\infty\) 边,两端一定有被割掉的,所以就是一个点覆盖。

复杂度:\(O(m\sqrt n)\)

【柯尼希定理】

二分图最小点覆盖 = 最大匹配。(无权

所以可以直接求最大匹配,然后得到最小点覆盖,再 n - 最小点覆盖得到最大独立集。

【带权】

带权之后,最大匹配和最小点覆盖就不同了。但是最小点覆盖和最大独立集还是可以互相转化。

【带权二分图最小点覆盖】

最小点权和最小点数点覆盖

把网络流求最小点覆盖中,\(s\) 向左边连的边 以及 右边向 \(t\) 连的边 的容量 设为点权。

求最小割。

复杂度:上限 \(O(nm)\)

如果有负权点:肯定是先把所有负权点选了,然后看每一条边有没有覆盖到。把所有没覆盖到的边用网络流做。

最大点权和最小点数点覆盖

把所有点权取反,就变成上一种情况了。

【二分图带权匹配】

先保证匹配最大,再保证权值。

有点权:把每条边的权设定为两端的点权之和,变成有边权的情况。

有边权:

  1. 费用流。中间的边的费用设定为边权,\(s\)\(t\) 的边费用为 \(0\),容量和不带权的一样,跑最大/小费用最大流。

    复杂度最差 \(O(n^2m)\),因为增广路长度最多 \(m\),所以最多分 \(m\) 次层;一轮增广 \(O(n)\);最大流 \(f\) 可以视为 \(n\)

  2. KM 算法:\(O(n^3)\)。但注意,KM 的 \(O(n^3)\) 经常跑满,有时候还没有费用流快。解决完美匹配问题

    对每个结点进行标号 \(lab\),使得 \(lab_u+lab_v\ge w(u,v)\)。(一定可以做到,因为可以赋值为无穷大)

    \(lab_u+lab_v=w(u,v)\) 的边 \((u,v)\) 称为相等边或紧边。

    当所有匹配边紧时,达到最大匹配。答案为 \(\sum lab\)。记原图为 \(G\),当前的紧边构成图 \(G'\)

    因为 \(\sum lab\ge \sum w\),故取相等时,\(\sum w\) 取最大。记左集为 \(U\),右集为 \(V\)

    1. 首先 \(u\in U\),令 \(lab_u\)\(u\) 邻边最大权;\(v\in V\),令 \(lab_v=0\)

    2. 对于 \(u_1,u_2,\dots,u_n\in U\),依次:

      • \(u\)\(G'\) 中未匹配,则从 \(u\) 出发搜 \(G'\) 的交错路并打标记。

      • 判断有无增广路。

      • 若有,增广结束(让 \(u\) 匹配上);无,调整 \(lab\)。怎么调整 \(lab\)

        \(x\)\(U\) 中标记点,\(y\)\(V\) 中无标记点,\(k\)\(V\) 中标记点。(这里的标记是上面交错路标记)

        不断重复这个过程,直到从 \(u\) 出发能找到一条增广路(直到从 \(u\) 出发能在 \(G'\) 中找到一个匹配的点):找到 \(lab_x+lab_y-w(x,y)\) 最小值 \(d\),然后对所有 \(lab_x-=d,lab_k+=d\)。显然这么做了之后,紧边仍然紧,而且至少让一条松边紧了。

【一般图最大匹配】

开花树算法(Blossom)

二分图当且仅当无奇环,开花树算法对奇环做了处理。

这里的“花”就是奇环。

因为奇环没法处理,直接把奇环缩点。原本连到奇环上的

原图存在增广路,当且仅当缩图存在增广路。

【题目】

稳定婚姻

教练曰:美国就变成一般图匹配,甚至自我匹配了。

就是二分图,注意夫妻之间没有连边。

初始让每个女人 \(i\) 的初始匹配都是男 \(i\)。然后枚举男 \(i\),尝试找增广路,如果找到了就不安全。

复杂度 \(O(nm)\)

变换序列

简化题意:

定义 \(d(x,y)=\min(|x-y|,n-|x-y|)\)。要求构造一个字典序最小的长度 \(n\) 的序列 \(T_i\),使得 \(d(i,T_i)\) 刚好是给定的 \(d_i\)。(或者输出不存在)\(n\le 10^4\)

我们构造一个二分图:若 \(d(i,x)=d_i\),则令 \(i\in A\)\(x\in B\) 连一条边。问题就是求是否存在完美匹配。

显然当要求 \(d(i,x)=d_i\) 时,至多有两个 \(x\) 满足,所以复杂度可以接受。

但问题是:怎么保证字典序最小?

考虑一个中间结果:不妨假设此时 \((0,T_0=1),(1,T_1=2)\) 已经匹配好了,且是最小的使得后面能匹配的匹配

因为 \(T_0,T_1\) 已经确定,后面改了肯定不优,我们直接锁定 \(T_0,T_1\),后面干什么都不能动。

接下来考虑尽量让 \(T_2\) 小。令 \(T_2\) 尝试匹配尽可能小的,记作 \(t\)。此时我们只需要检查哪个原本匹配 \(t\) 的 失配了,是否还能找到增广路,就能判断 \(T_2\) 能否可以 \(=t\)

如果真的匹配上了,因为字典序是贪心的,直接将 \(T_2\) 锁定为 \(t\)

当然如果 \(T_2\) 配不了 \(t\),就检查 \(t\) 更大的。

整个算法流程:先跑一个二分图匹配,然后挨个尝试变小。

复杂度是多少?

对于每个点,我们会从小到大枚举它所有邻边,尝试让那个失配的点找增广路。上面说了,一个点最多两条边,而找增广路是 \(O(m)\) 的,所以对于一个点是 \(O(m)\) 的,在这题里,也就是 \(O(2n)=O(n)\) 的。

所以总复杂度是 \(O(n^2)\) 的,当然这只是理论上限,实际上根本跑不满。

小行星

建立一个二分图:左右各 \(n\) 个点,分别表示 \(n\)\(n\) 列。对于一个小行星 \((x,y)\),则左边 \(x\) 和右边 \(y\) 之间连边。然后求最小点覆盖(最大匹配)即可。

因为左边 \(x\) 和右边 \(y\) 连边,就要求了 \(x,y\) 中必须选一个,对应了一颗小行星要么被行消除要么被列消除。

线段

把横向、纵向的线段作为二分图的左右两边。有交点的线段相互连边。

求最大独立集 = n - 最小点覆盖 = n - 最大匹配。

骑士共存问题

把每个格子抽象为结点,可以相互攻击的结点连边。

为什么是二分图?因为国际象棋棋盘黑白染色。

然后求最大独立集。

考虑用染色方法构建二分图。

长脖子鹿放置

染色方法(证明是二分图的方法):一行一种颜色。

方格取数问题

每个格子抽象为结点,相邻格子代表的结点连边,点权是格子上的数。求最大点权和独立集。

用 sum - 最小点权和点覆盖 求。

太空飞行计划

左半边点代表实验,右半边点代表仪器。

\(s\) 向左半边点连边,容量为这个实验的收益。

右半边点向 \(t\) 连边,容量为这个仪器的花费。

一个实验 \(u\) 向它所需的所有仪器连边,容量为 \(+\infty\)

考虑最小割,对于一个到 \(s\)(或 \(t\)) 的边被割的点:

  1. 若是代表实验的点,代表不做这个实验。

  2. 若是代表仪器的点,代表这个仪器。

每个边割了,都是负收益。

这么做的意义是什么:对于一条 \(+\infty\) 边,连 \((i,j)\) 两点:代表要么不做实验 \(i\),要么买仪器 \(j\)

然后用所有实验的总收益减去最小割。

怎么理解?对于实验 \(i\) 和仪器 \(j\),只有(要做 \(i\) 但是不买 \(j\))这一种情况是矛盾的,于是用 \(+\infty\) 的边代表这个矛盾。

最后的问题:怎么求最小割?

注意不能检查每条边的容量,因为最大流流过去,一条增广路上随便选一条边都有可能。

设最小割为 \(C\),枚举每一个点,先把它到 \(s/t\) 的容量变成 \(0\),跑最小割。看一下最小割是否是 \(C-w\):如果是,则必存在一个最小割方案,删除了这个点;如果更大,则恢复这条边到原来的容量。

复杂度 \(O(nm\times n)\)

Card Game

二分等级。

每张卡片抽象为一个结点,魔力值和为质数的卡片之间连边。

尝试让二分图的左右两边代表魔力值为奇/偶的卡片。如果是“和不能为奇质数”,就是二分图;但可惜现在不是。

如果和为 \(2\),一定是 \(1+1\),我们尝试特判这种情况:所有 \(1\) 魔力值的结点只留一个能量最大的。

然后构建二分图,点权是卡片的能量,求最大权独立集。

posted @ 2024-02-02 09:08  FLY_lai  阅读(8)  评论(0编辑  收藏  举报