【学习记录】有正能量的二分图

帽帽猫在这里放一个传送门
图标

严格按照,nodgd 做梦梦到的单子,进行记录。


基本算法

二分图判定

逻辑:当且仅当环长都是偶数。

算法:DFS/BFS/并查集

二分图染色。

匈牙利算法

求最大匹配。

时间复杂度 \(O(nm)\):每个点增广一次,每次 \(O(m)\)

熟练默写模板

点击查看代码
bool _find(int x){
    if(vis[x]==now) return false;
    vis[x]=now;
    for(int i=head[x];i!=0;i=g[i].nxt){
        int v=g[i].t;
        if((!l[v])||_find(l[v])){
            l[v]=x;
            return true;
        }
    }
    return false;
}
int main(){
    for(int i=1;i<=n;i++){
        now=i;
        if(_find(i)) ans++;
    }
}

如何卡满上界

不加优化时,完全图即可卡到 \(O(n^3)\),带一个小常数。

根据完全图选匹配边的方式也可以构造卡满 \(O(nm)\) 的图。

常用优化方法

决定直接抄袭 OI-Wiki。

  • 没有划分点集的图,先二分图染色划分点集。
  • 选取点数更少的一边作为左部点。
  • 标记用时间戳处理。
  • 寻找增广路时,优先考虑未匹配的右部点
  • 避免特殊数据卡满,匹配前随机打乱边和点的顺序。感觉这个是最有用的。

来自 duang:

  • bitset 优化 BFS 匈牙利。时间复杂度为 \(O(\frac{n^3}{w})\)

证明!

这是不存在于 nodgd 单子上的内容。

Berge 引理:对于图 \(G=(V,E)\) 和它的一个匹配 \(M\),匹配 \(M\) 是最大匹配,当且仅当不存在相对于匹配 \(M\) 的增广路。

证明:简单来说,假设有一个更大的匹配 \(M'\),拿出↗来↗→一个新图叫做 \((V,M \oplus M')\)。异或相当于保留了在两种匹配中状态(是否匹配)不同的边。
注意到新图中点的度数只可能为 0,1,2。这说明新图一定由一些环(并且为偶环),路径和孤点组成。若 \(M'\) 的匹配边数量大于 \(M\),差值一定出自于路径。而这样的路径在原图中是增广路。矛盾,所以得证。

例题 [EC Final 2022] Magic

这道题的条件给的非常巧妙。

不妨倒着考虑修改的区间。发现最后一个加入的区间 \([l,r)\) 会恰好使 \((l-1,l)\)\((r-1,r)\) 这两个点对产生贡献,并使得所有 \(i\in[l+1,r-1]\)\(i-1\) 后续无法贡献

对于后续加入的区间,就需要考虑前面加入的区间是否让当前区间的端点值无法贡献了。发现这是一个先后顺序影响贡献的排序问题。

对于两个区间,可能有三种情况:

  • 若为包含关系,则钦定小区间必须在大区间后修改;
  • 若交集为空,则二者之间互不影响;
  • 若相交,则必须舍弃 左边区间的右端点 或 右边区间的左端点。这个限制关系可以用图中的边来表示。

相当于要在二分图上选择尽量多的点,使得任意两点不相邻。这是最大独立集问题。

由于数据范围和空间限制,用 bitset 优化即可通过。

很巧妙。如果给的条件稍微变一点都做不了了。很厉害。

技巧:

  • 正面考虑麻烦不妨倒着考虑

Hopcroft-Karp 算法

求最大匹配,是匈牙利的优化算法。

本质:把匈牙利改成 BFS 找增广路+ DFS 多路增广,即未显示建图的 Dinic。

时间复杂度 \(O(m\sqrt{n})\):增广路长度每轮严格递增,所以至多 \(O(\sqrt{n})\) 轮。

如何卡满上界

不知道。

duang 是不是讲了。但是我忘了。


KM 算法

求最大权匹配。

流程:设置点权并动态调整,对 边权等于两点权值和 的边跑匈牙利。即未显示建图的费用流。

时间复杂度 \(O(n^3)\),严格优于费用流 \(O(n^2m)\),用于卡常。

但是我只会写费用流的。


经典问题

最大匹配(边独立集)

定义:选最多的边,没有公共顶点。

用朴素匈牙利解决。


最小点覆盖

定义:选最少的点,使每条边至少一个端点被选择。

Kőnig 定理

最小点覆盖 = 最大匹配。

证明:图从 OI-Wiki 拿的。
\(X\) 为左部点,\(Y\) 为右部点,\(U\) 为未匹配的左部点,\(Z\) 为以 \(U\) 中的点为起点,通过交错路能到达的所有点。
有结论:最小点覆盖的点集 \(C=(X\setminus Z)\cup(Y\cap Z)\)

首先,\(C\) 一定是一个点覆盖。这是好理解的,对于 \(Y\setminus Z\) 中的点,它们连向的左部点一定也不属于 \(Z\),因此这些边都有一个端点被选择;同理,对于 \(X\cap Z\) 中的点,它们连出的所有边一定在 \(Y\cap Z\) 中有端点。
证明 \(C\) 是最小点覆盖。显然最小点覆盖一定大于等于最大匹配,即 \(|C|\ge |M|\),因此需要证明该点集选择的点都是匹配点。
显然 \(X\) 一侧选择的点一定都是匹配点。
假设 \(Y\) 侧选择了一个非匹配点,说明通过一个 \(U\) 中的点,经过交错路可以到达该点,且首尾两条边均为未匹配边,这是一个增广路。矛盾,因此 \(Y\) 侧选择的点均为匹配点。
得证。

方案构造

上述证明中的 \(C=(X\setminus Z)\cup(Y\cap Z)\)

写代码的话,按照这个模拟应该就行了。


最小边覆盖

定义:选最少的边,使每个点都有相邻边被选。

  1. 最小边覆盖 \(= n_1+n_2-\) 最大匹配

证明:来自 deepseek。

  1. 从最大匹配构造边覆盖
    \(M\) 是二分图的一个最大匹配,覆盖了 \(2|M|\) 个顶点。剩余 \(|V| - 2|M|\) 个顶点未被覆盖。对于每个未被覆盖的顶点,任选一条与其关联的边加入集合 \(S\)。这些边不会连接两个未被覆盖的顶点(否则可加入匹配,与最大性矛盾),且每条边最多覆盖一个未被覆盖的顶点。因此 \(|S| = |V| - 2|M|\)。取 \(L = M \cup S\),则 \(L\) 是一个边覆盖,且

    \[|L| = |M| + (|V| - 2|M|) = |V| - |M|. \]

    故最小边覆盖数不超过 \(|V| - |M|\)

  2. 从最小边覆盖导出匹配
    \(L\) 是一个最小边覆盖。考虑由 \(L\) 导出的子图,其每个连通分支均为树(若有环则可去掉一条边仍覆盖所有顶点,与最小性矛盾)。从 \(L\) 中可构造一个匹配 \(M'\):在每个树形分支中,选取尽可能多的不相交边。可以证明,\(L\) 中每条不在 \(M'\) 中的边必须恰好覆盖一个未被 \(M'\) 覆盖的顶点(否则可去掉,与最小性矛盾)。设未被 \(M'\) 覆盖的顶点数为 \(x\),则每条不在 \(M'\) 中的边恰好覆盖一个这样的顶点,故

    \[|L| - |M'| = x. \]

    \(M'\) 覆盖了 \(2|M'|\) 个顶点,故 \(x = |V| - 2|M'|\),代入得

    \[|L| = |V| - |M'|. \]

    由于 \(M'\) 是匹配,有 \(|M'| \leq \text{最大匹配数}\),所以

    \[|L| \geq |V| - \text{最大匹配数}. \]

  3. 结合两者
    由第一步得最小边覆盖数 \(\leq |V| - \text{最大匹配数}\),由第二步得最小边覆盖数 \(\geq |V| - \text{最大匹配数}\),故等式成立。

  1. 最小边覆盖 \(\ge\) 最大匹配

证明:选择所有匹配后,仍不能保证所有顶点均被覆盖。

取等条件:原图存在完美匹配。

  1. 构造方案
    按照证明中的方式模拟即可。

边支配集

定义:选最少的边,使每个未选边都至少存在一条已选边有公共顶点。

  1. 边支配集 \(\le\) 最大匹配, 边支配集 \(\le\) 最小点覆盖

证明:好像会证,呜呜呜泪目了。
目前已经有了一个最大匹配,选取最大匹配中的边。如果存在一条边使得其没有被选择且任意相邻边都没有被选择,那么最大匹配应该会更大。所以不存在这样的边。所以令最大匹配中的边为被选择的边一定可以得到一个合法的边支配集。所以边支配集 \(\le\) 最大匹配 = 最小点覆盖。

  1. 怎么做?这个好像真做不了。NP-Hard。

最大独立集

定义:选最多的点,使得两两不相邻(没有直接连边)。

结论:最大独立集 = 最小点覆盖的补集 = \(n_1+n_2-\) 最大匹配。

证明:由 \(C\) 是最小点覆盖,则 \(E\) 中每条边至少有一个端点在 \(C\) 中,没有一条边的两个端点都出现在 \(V\setminus C\) 中,则 \(V\setminus C\) 为独立集。
\(|C|\) 最小时,\(|V\setminus C|\) 最大。

构造方案

求出最小点覆盖即可。


DAG 最小路径覆盖

定义:选最少的简单路径,每个点恰好出现在一条路径中。

构造:把每个点拆成两个,一个为入度点,一个为出度点。原图中的边重新连到这个新的二分图上。

这个图的一个匹配可以理解为一个简单路径划分。每个点最多有一个入度,一个出度。达到最大匹配时,意味着选的边最多,即为最小路径覆盖。

DAG 最小可重路径覆盖

定义:选最少的简单路径,每个点至少出现在一条路径中。

构造:可重路径等价于选择的一条路径上可能只有少数点是此前没有被覆盖过的

因此对原图做传递闭包,再按照最小路径覆盖的方法构造即可。


二分图博弈(UVG 游戏)

规则:二分图(或无向图)上有一枚棋子,两人轮流操作将棋子移动到相邻且未到达过的点,无法行动则失败。

必胜态的结论

若起点一定在原图的最大匹配中,则先手必胜。

证明(感性):起点在匹配中,则先手第一步走匹配边,后手就只能走非匹配边。由于该匹配是最大匹配,所以不存在增广路,因此最后一步一定由先手走出。

但若存在方案,使得起点不在最大匹配中,后手就可能在未来的某一步 走另一个匹配中的匹配边,让先手落入必败境地。

所以为什么后手翻盘之后先手不能再翻来着。忘了啊。

必胜策略:先手每次走匹配边。对后手来说,找机会翻盘即可。

看了 @jr_zch 大佬的博客,我学会了。

抄袭:

把访问过的点看作被删除。

按照博弈论的流程,分两步来证明该结论。

  • 任意的必胜态都能到达必败态。
    考虑原图的一个最大匹配边集 \(M\),因为 \(u\) 是必胜点,所以一定存在 \((u,v)\in M\)
    删去点 \(u\) 之后,新图的最大匹配数会减小 \(1\),且 \(M\setminus (u,v)\) 是其中一种最大匹配方案,那么可知 \(v\) 在新图中是必败点。

  • 任意的必败态都只能到达必胜态。
    因为 \(u\) 不被所有最大匹配方案所包含,所以删去 \(u\) 之后的新图的最大匹配数不变,令这个值为 \(p\)
    对于任意与 \(u\) 相邻的点 \(v\),若 \(v\) 是必败点,则有一种匹配方案 \(M'\),满足 \(|M'|=p,(u,v)\notin M'\)
    那么可以原图中构造出一个匹配方案为 \(M\cup \{(u,v)\}\),其大小为 \(p+1\),与原图的最大匹配数为 \(p\) 相悖。
    \(v\) 一定是必胜点,证完了喵喵喵。

例题 [ICPC 2025 WF] Blackboard Game

没做。


相关定理

我写累了。

Hall 定理

Dilworth 定理

证明

Mirsky 定理

Tutte 定理


其他问题

回文匹配

设左侧点编号 \(1,2,\dots,n\),规定对于任意 \(i\),点 \(i\)\(n-i+1\) 要么都在匹配中,要么都不在匹配中。求最大回文匹配。

字典序最小的最大匹配

例题 [NOI2009] 变换序列

归纳总结:什么情况下匈牙利可以保证字典序?

题目

Alternating Paths

垃圾题。

Blackboard Game

Anti-Plagiarism

Skandi

[CTSC2008] 祭祀

虽然我还是不太会证明 Dilworth 定理,但是这道题我会了。

题意就是求一个 DAG 的最长反链,即点两两之间都不可达。有 Dilworth 定理,最长反链大小等于最小链覆盖。这里的最小链覆盖就是最小可重路径覆盖。

先求传递闭包,再用前文提到的方法求最小可重路径覆盖。

构造方案:

所有满足 \(x_{out}\)\(x_{in}\) 均在新图求出的最大独立集中的 \(x\),构成原图的最长反链。

换个方式讲,就是

唉算了我不想写了。


感谢阅读 ˶ᗜ ˰ ᗜ˶ 。猫猫帽帽猫
图标

图标

图标

图标

图标

图标

图标

真的没有人觉得帽帽猫可爱吗。好伤心。

posted @ 2026-01-04 15:54  PhainonK  阅读(129)  评论(12)    收藏  举报