大学图论第 6 讲:网络流与二分图匹配——对偶性让瓶颈自己现形

《把定理跑出来》系列收官之作。网络流是本科图论的最后一座山,也是前三讲所有工具的汇合点:增广路里跑着最短路式的搜索,匹配转化用着第 3 讲的多项式自信,Hall 定理的验证靠第 2 讲的遍历。

这一讲跑三件事:最大流最小割定理的对偶性 (100 组随机网络数值验证)、Edmonds-Karp 与 Dinic 的增广次数差距 (单位容量网络实测 5.8 倍)、二分图匹配的三方对拍与 Hall/Konig 双定理。全文 8 张图由文末代码生成,种子固定,可复现。

摘要

  • 最大流最小割定理 :100 组随机网络实测------每组网络的最大流值与最小割容量严格相等(图 1 的实例里,流值 3 = 两条入汇边的容量 1+2);对偶性让"瓶颈"从约束变成答案;
  • Edmonds-Karp vs Dinic :单位容量二分匹配网络上(half=400,总点 802),EK 37.69ms vs Dinic 6.48ms(5.8 倍)------容量全 1 时增广次数 = 匹配数 ≈ 400 次 BFS,Dinic 的分层 phase 只有 O(√E) 个;
  • 二分图匹配三方对拍 :Kuhn / Hopcroft-Karp / 最大流转换,n=30~240 四档规模答案完全一致 ;速度分层------HK 在 n=240 时比 Kuhn 快 10.5 倍;
  • Hall 定理 :min(|N(S)|−|S|) ≥ 0 ⟺ 存在饱和左部的匹配,400 组随机二分图全对;实测反例:7 个任务的可做集合只有 5 个志愿者------|N(S)|−|S| = −2,落单是数学必然;
  • Konig 定理 :最大匹配 = 最小点覆盖,构造法验证 200/200------从最大匹配沿交替路标记,"未标记左点 + 已标记右点"就是一个合法点覆盖;
  • 应用闭环:8 任务 × 6 志愿者的分配问题------最大匹配 6,2 个任务落单是 Hall 条件的必然而非调度不力。

关键词:网络流;最大流最小割定理;Edmonds-Karp;Dinic;二分图匹配;匈牙利算法;Hopcroft-Karp;Hall 定理;Konig 定理;对偶性

目录

  • [1. 网络流:给图加一个"运输"的语义](#1. 网络流:给图加一个"运输"的语义)
  • [2. 最大流最小割定理:对偶性让瓶颈自己现形](#2. 最大流最小割定理:对偶性让瓶颈自己现形)
  • [3. Edmonds-Karp vs Dinic:增广次数的差距](#3. Edmonds-Karp vs Dinic:增广次数的差距)
  • [4. 二分图匹配 = 单位容量最大流](#4. 二分图匹配 = 单位容量最大流)
  • [5. Hall 定理:落单是数学必然](#5. Hall 定理:落单是数学必然)
  • [6. Konig 定理:最大匹配 = 最小点覆盖](#6. Konig 定理:最大匹配 = 最小点覆盖)
  • [7. 系列收官:六讲的知识地图](#7. 系列收官:六讲的知识地图)
  • [8. 复现指南](#8. 复现指南)
  • [9. 写在最后](#9. 写在最后)

1. 网络流:给图加一个"运输"的语义

网络 = 有向图 + 边容量(这条边最多能"运"多少)+ 源点 s 和汇点 t。"最大流"问的是:从 s 到 t,单位时间最多能运多少?

它在课程里的位置非常微妙------前面学的遍历、最短路、MST 都是"一个算法解一类题",而网络流的正确性来自一条深刻的对偶定理:

最大流最小割定理(Ford--Fulkerson, 1956):一个网络的最大流值,等于把顶点切成两半时"跨割容量之和"最小的那个割的容量。

这句话意味着:优化问题(最大流)的答案,和约束问题(最小割)的答案,是同一个数。第 3 篇第一次见到这个结构(MST 的瓶颈性质),这一讲它是主角。

2. 最大流最小割定理:对偶性让瓶颈自己现形

实验:100 组随机网络(n=6~12,边容量 1~9 随机),每组分别求最大流(Dinic)和最小割(残量网络中从 s 出发的可达集 S,跨割容量):

图 2:100/100 组------最大流值与最小割容量严格相等。

看一个具体实例(图 1):

图 1:12 点随机网络,流值 3 = 最小割容量 3。 红色两条边(7→11 容量 1、10→11 容量 2)是汇点 t 仅有的入边------算法没有被告知"t 的入边是瓶颈",是对偶性让瓶颈自己现形。这就是最小割定理最迷人的地方:你不用猜瓶颈在哪,跑完最大流它自动浮出来。

工程对应物:第 1 篇第 6 节的"跨河通勤能力腰斩 53%"------那时我们就用过这个定理,只是没有点名。

3. Edmonds-Karp vs Dinic:增广次数的差距

求最大流的两代经典算法都基于"增广路":找一条 s→t 的可行路径推流,重复到无路可增。

  • Edmonds-Karp :每次 BFS 找最短增广路,O(VE²);
  • Dinic :BFS 分层 + DFS 找阻塞流,O(V²E)。

纯看复杂度差别不大。但把网络换成单位容量的二分匹配网络(容量全 1 时增广次数 = 匹配数,每次增广 EK 都要一次全图 BFS,而 Dinic 的分层 phase 只有 O(√E) 个):

图 3:half 从 10 到 400。 half=400(总点 802)时 EK 37.69ms vs Dinic 6.48ms(5.8 倍)------而且 EK 曲线的斜率明显更陡(增广次数随规模线性涨、每次 BFS 全图扫)。

一个诚实的补充:随机大容量图上两者几乎打平(几轮增广就满流)------算法差距只在"增广次数多"的网络上显形。这也是选型的真实逻辑:先想清楚你的图属于哪种形态。

4. 二分图匹配 = 单位容量最大流

第 2 篇讲派单时预告过:二分图最大匹配可以转成最大流------加超级源 S 连左部(容量 1)、右部连超级汇 T(容量 1)、左到右的可行边容量 1。匹配数 = 最大流值。

课程版三方对拍:同一个二分图,Kuhn(匈牙利增广)、Hopcroft-Karp(分层增广)、最大流转换(Dinic),n=30~240 四档:

图 4:左:三种算法的匹配数逐点一致(断言保证);右:耗时分层------n=240 时 Kuhn 4.52ms、HK 0.43ms(快 10.5 倍)、最大流转换 4.70ms。

这张图把两条线索焊在了一起:匹配 = 流(定理),HK = Dinic 的二分图特化(直觉)------二分图的层次结构让 Dinic 的 phase 数恰好变成 O(√V),于是 HK 就是"Dinic 特化的匹配算法"。学懂了网络流,匹配算法全家桶免费附赠。

5. Hall 定理:落单是数学必然

匹配数 < 任务数时, managers 的第一反应是"调度不力"。Hall 定理说:未必------有些落单是数学必然。

Hall 定理:存在饱和全部左点的匹配 ⟺ 对任意左点子集 S,|N(S)| ≥ |S|(它们的邻居至少和它们一样多)。

实测 400 组随机二分图:min(|N(S)|−|S|) ≥ 0 与"存在饱和左部的匹配"400/400 完全一致(min 用小规模枚举全部 S⊆L 计算,匹配用 HK 计算------两个独立方法)。

图 5:实测反例。 8 个任务里前 7 个的可做集合只有 5 个志愿者------|N(S)|−|S| = 5−7 = −2 < 0,Hall 条件违反:无论调度器多聪明,至少 2 个任务落单。

Hall 条件的价值在于"一眼可查":不用跑匹配算法,扫一遍每个任务子集的邻居数就能预判匹配结果。这就是它比"试一试"高级的地方。

图 5b:应用闭环。 8 任务 × 6 志愿者的分配实例:最大匹配 6,任务 4、5 落单(红圈)------绿边是选中的指派,落单是 Hall 条件的必然而非调度不力。

6. Konig 定理:最大匹配 = 最小点覆盖

二分图的第二个对偶定理:最大匹配的边数 = 最小点覆盖的点数(选最少的顶点,让每条边至少碰到一个)。

构造法验证:从最大匹配出发,沿"非匹配边(左→右)、匹配边(右→左)"从所有未匹配左点做交替路标记------未标记的左点 + 已标记的右点就是一个最小点覆盖:

图 6:200 组随机二分图,构造出的点覆盖全部合法(每条边至少一端被盖)且大小恰等于最大匹配数------200/200。

应用原型:用最少的摄像头盯住所有通道、用最少的拦截点切断所有走私路线、用最少的补丁盖住所有漏洞------凡"选最少的点覆盖所有的边",都是 Konig 在工作。

7. 系列收官:六讲的知识地图

图 8:六讲知识地图。 从第 1 讲的握手定理到本讲的 Hall/Konig,每一讲都是同一个动作:课本给结论,我们造样本,让结论在数据里再发生一次。

六讲的数字账本:

讲次 验证的定理/结论 关键实测
第 1 讲 概念与存储 握手定理、计数公式、度分布 5 类图全等;存储边界反转
第 2 讲 遍历与连通 O(n²)/O(n+e)、相变 序列差异 91%;138 倍;c=ln n
第 3 讲 欧拉与哈密顿 判定×构造、规模墙 900+200 组对拍;NP 完全露脸
第 4 讲 最短路三件套 负权失效、Floyd 的 k 误差 100%;路径重建 30/30
第 5 讲 生成树与拓扑 切割性质、关键路径 1429/1429;延误实验
第 6 讲 网络流与匹配 对偶性、Hall/Konig 100/100;400/400;200/200

8. 复现指南

复制代码
graph-course/
├── course6.py    # 六组实验(对偶/横评/匹配三方/Hall/Konig/应用,~330 行)
├── figs6.py      # 8 张配图
├── results/course6.json
└── figures/
bash 复制代码
python course6.py   # → results/course6.json(约 1 分钟)
python figs6.py     # → 8 张图

依赖:本讲复用第 1 篇的 Dinic 骨架(sys.path 引入 graph-blog/kernel.py)。正确性断言:EK/Dinic 流值相等(每档规模)、匹配三方对拍一致(assert)、Hall 与匹配存在性 400 组一致、Konig 构造 200 组合法且等大小。种子 SEED=2026,确定性结果逐字节一致。

9. 写在最后

六讲写完,这个系列想传达的方法只有一条:

图论的每一个定理,都值得在计算机里重新"发生"一次。 背下来的握手定理会忘,跑过的 264 = 264 不会;抄来的"Hopcroft-Karp 快"没有体感,亲手对拍出的 12.7 倍才是选型时的肌肉记忆;教科书上"NP 完全"四个字很抽象,亲眼看一次回溯在阈值附近超时 22/25 就再也不会误解它。

以及最重要的------当算法给你的答案违反直觉时,先怀疑模型的假设,再怀疑算法的实现,最后才轮到接受"反直觉"本身。第 4 讲的单位换算 bug、第 5 讲的 vl/ve 混用、本讲第一版割容量把"入边"也算了进去------每一次"错误的结果"背后都是一个值得写进博客的洞见。

数据不会说谎,但会考验你提问的方式。

系列完结。六讲全部代码与数据:graph-course/(course1~6.py + figs*.py + results/*.json)。祝每一场考试、每一次面试、每一个工程决策,都有跑出来的数据撑腰。


系列目录:第 1 讲 基本概念与存储 · 第 2 讲 遍历与连通 · 第 3 讲 欧拉图与哈密顿图 · 第 4 讲 最短路三件套 · 第 5 讲 生成树与拓扑排序 · 第 6 讲 网络流与匹配(本篇,完结)

相关推荐
方便面不加香菜1 小时前
C++ 关于多态的知识点讲解
开发语言·c++
没有钱的钱仔1 小时前
最大似然估计(MLE)通俗理解
算法·机器学习·概率论
yi0111 小时前
LeetCode 424. 替换后的最长重复字符|不定长滑动窗口:如何判断窗口是否合法?
笔记·python·算法·leetcode·双指针·滑动窗口
jimy11 小时前
C++ 类成员函数的内联定义(inline)详解
开发语言·c++
Nebula_g1 小时前
JavaSE高级:动态代理
java·开发语言·算法·javase
垆边人似月.1 小时前
华为题:盛最多水的容器
数据结构·算法
杨逢昌工厂6S管理1 小时前
116——杨逢昌:归位三定闭环法的旺季轻量化执行方案与工具清单
经验分享·笔记·职场和发展·学习方法
怦然丶心动1 小时前
用 Java 把干支历法算清楚:从节气切年到可读摘要
java·算法·vue·独立开发·spring boot / spring
青春逝如流水2 小时前
Java 线程与操作系统、硬件的关系:状态、映射与差异
java·开发语言·多线程·ai文章