NOI 一轮复习 I:二分图网络流
NOI 一轮复习 I:二分图网络流
阅读须知:
本系列博客主要为个人复习所用,可供各位参考。
整理的知识点不会涉及较为偏僻的知识点,以 NOI 考察过的知识点为主。
按照目前的想法,想分成 数据结构、分治、数论函数、线性代数、连通性、二分图网络流、计算几何、字符串、组合计数、杂论、论文选做 这些板块进行整理,由于只是最初设想,想必此后会有更新。
知识清单/目录:
- 二分图概念与判定
- 二分图最大匹配
- 二分图最大权匹配
- Hall 定理
- 网络最大流
- 最小费用最大流
- 上下界网络流
- 网络流扩展与建模举例
注意事项:
- 其实本文的一大重点是证明各种二分图和网络流算法的理论基础,模板并不会详解,建模也只是一个部分。
- 限于作者水平,本文一般不讨论网络流算法的时间复杂度,在分析例题复杂度时将其视为一个整体模块。
- 本文所讨论的图(特别是当边无权时)一般为简单图,且一般认为
O(|E|)\ge O(|V|) 。
因为网络流 24 题比较老旧,就不想写了。
将在 1~2 周内随缘更新。
1. 二分图概念与判定
定义:对于无向图
这即是说,
由此,我们也可以用二染色来定义二分图:二分图是可以被二染色的图。
这里存在一个小性质:若二分图
下面给出二分图的一个性质和判定定理:
定理:图
证明:
若
当
推论:二分图
推论:无向图
根据上面的定理和证明过程,我们可以得到判定给定无向图是否是二分图的算法:
- 设给定的图为
G=(V,E) ,由第二条推论,只需分别判定G 的每个连通分量是否是二分图。 - 对于
G 中的一个连通分量,对其进行 DFS,求出一棵搜索树并记录每个点的深度,遇到返祖边时,判定这条边两端点的深度是否同奇偶,如果同奇偶则G 不是二分图,若对于所有返祖边都有两端点深度不同奇偶,则G 是二分图。 - 在实现时,只需要记录每个点深度的奇偶性,事实上这等价于模拟对
G 进行二染色的过程。 - 时间复杂度为
O(|E|) 。
事实上,结合上面的过程还可以得到一些比较显然的小结论:例如连通图
二分图有关路径长度的浅显性质:二分图中任意两点间路径经过的边数奇偶性确定,反之,一个连通非二分图中任意两点间路径经过的边数奇偶性都不确定。
例题
1 :[Luogu P1330] 封锁阳光大学给定无向图
G=(V,E) ,求最小的点集A\subseteq V 使得\forall (u,v)\in E 有u\in A 或v\in A 恰好成立其一,或报告无解。
容易发现,若存在这样的
当
时间复杂度为
例题
2 :[NOIP 2010] 关押罪犯有
N 个罪犯和两座监狱,罪犯间有M 对形如(u,v,w) 的关系表示u,v 两名罪犯若在同一监狱则会发生影响力为w 的冲突事件,求合理分配每个罪犯到某一座监狱后,发生的最大影响力的冲突事件的影响力最小值。
二分答案
时间复杂度为
例题
3 :[HNOI 2019] 校园旅行给定无向图
G=(V,E) ,每个点有0 或1 的一个标记,有q 组询问,每组询问给定s,t\in V ,你需要求出是否存在一条s\to t 的路径P ,使得路径经过的点的标记拼成一个回文串。
考虑一个由标记全为
当这个连通分量
如果它是二分图,显然只需要保留一棵生成树即可,否则只需要保留一棵生成树的基础上任意增加一个奇环,例如增加一条自环。
(甚至不必是生成树,任意一个连通二分图均可)
同样的道理,当我们把这样一个连通块视为一个整体时,连接不同连通块的边也可以通过相似的方法缩成只剩一个生成树(由于连通块已经染色,所以肯定是二分图)。
(这一部分只能是生成树,不能是任意一个连通二分图)
可以论证,大小为
此时
时间复杂度为
2. 二分图最大匹配
二分图最大匹配问题,即对于给定的二分图
我们下面将介绍求解二分图最大匹配的匈牙利算法。
令
匈牙利算法依赖一个重要结论:
必要性容易证明:若存在增广路,则将增广路上全体非匹配边改为匹配边,匹配边改成非匹配边,就得到了一组更大的匹配。
充分性证明:若
upd 一个更严谨的充分性证明:考虑一个最大匹配
上面充分性的证明已经部分蕴含了匈牙利算法的内容:
-
枚举
i=1,\ldots,n ,其中n 为左部点数量,时刻维护左部点当前前缀1,\ldots,i-1 与全体右部点的一组最大匹配P ,考虑将i 加入: -
以
i 为端点进行 DFS 寻找增广路,假设寻找以左部点x 开始的增广路,首先枚举x 的邻居y ,若y 是非匹配点或者从y 匹配的点出发存在增广路,那么我们就找到了一条以x 开始的增广路(对于前者,x\to y ,对于后者,x\to y\to z\to \ldots ); -
如果找到了一条增广路,答案增加
1 ; -
为了控制算法复杂度,在对于每个
i 寻找增广路时,如果从一个x 出发时寻找失败,下次就可以直接返回,如果从一个y 的匹配点出发时寻找失败,下次也不必再检查y 。
匈牙利算法基于贪心原则:一旦一个点进入匹配,就不会重新成为非匹配点,因此当找不到增广路时表示
由此,我们可以知道:若将匹配的左部点记为
简单说说二分图匹配和匈牙利算法的一种组合理解:
考虑从拟阵交的角度刻画二分图最大匹配问题,令
以
- 显然,
\varnothing\in I_1 ; - 遗传性:显然若
A\in I_1 ,则对于B\subseteq A 有B\in I_1 ; - 交换性:若
A,B\in I_1 ,|A|<|B| ,任取B 到处子图中一个度数为1 而在A 导出子图中度数为0 的点,将其对应的边加入A 中,仍然在I_1 中。
那么匹配就是
回想拟阵交中的扩展过程,我们维护当前最大交
例题
4 :[NOI 2009] 变换序列给定数列
A_{1\ldots n} ,求字典序最小的排列P_{1\ldots n} 使得|P_i-i|=A_i 。
考虑建立二分图,左右部各有
本题的匹配比较特殊,去除所有一度点后形成了若干个环,每个环只有两种完美匹配,尝试字典序小的一种即可。
二分图最大匹配还可以用来解决一些其他模型。
二分图最小点覆盖
最小点覆盖问题指的是在给定图中选择尽量少的点,使得每条边至少有一个点被选。
我们考虑将二分图最大匹配写成线性规划形式,每条边视作变量,每个点视作限制:
其中
我们可以证明:上面问题中的代价矩阵是一个全幺模矩阵,因此其最优解等于整数规划解,即
(因为证明过程比较复杂,这里不写了,需要注意的是,若是一般图匹配则此处矩阵不是全幺模矩阵。)
将其对偶:
也就是说每条边的两个端点中至少要选一个,这也就是最小点覆盖问题了。
根据强对偶定理,我们可以得到:
定理:二分图最小点覆盖大小等于最大匹配大小。
随后,我们给出一种最小点覆盖的构造方法:
- 在求完最大匹配后,从二分图的每个左部未匹配点出发进行一次寻找增广路,然后将途径的所有点设为已经过标记。
- 取左侧所有未标记点和右部所有标记点,它们构成一组点覆盖。
- 下面证明这是一组点覆盖:如果存在一条边两端都没有选,说明其左侧是标记点,右侧是非标记点,但是在那个左侧点被标记后,右侧的点随后就会被经过,所以这是不可能的。
- 下面证明这组点覆盖的大小等于最大匹配大小:对于每条匹配边,或者左侧右侧同时被标记,或者同时没被标记,因此必定恰有一个点被选;而对于一条非匹配边,假设左侧点不是匹配点,那么必然被标记,假设右侧点不是匹配点,那么必然不被标记(否则找到了一条增广路),因此只有所有匹配边的恰好一边在这组点覆盖中。
实际上,我们还容易证明任何一组点覆盖大小
二分图最大独立集
最大独立集问题指的是在给定图中选择尽量多的点,使得其导出子图不含边。
对于任何一张无向图,我们有如下定理成立:
定理:最大独立集大小与最小点覆盖大小之和等于点数。
这是因为任何一组独立集取补后就得到一组点覆盖,独立集与点覆盖是一一对应的。
所以在二分图中我们就有:
定理:二分图最大独立集大小与最大匹配大小之和等于点数。
例题
5 :求在
n\times m 棋盘上最多放置多少个不会互相攻击的骑士。
对于格子
值得注意的是,许多类似的棋盘问题都可以用黑白染色的方法转化成二分图相关的问题。
与本题类似还有 Luogu P5030 之类,注意每题的染色方法可能不同。
二分图最小边覆盖
最小边覆盖的定义类似最小点覆盖,即用最少的边覆盖所有的点。
如果不存在孤立点,则二分图最小边覆盖等于最大独立集大小,即总点数减去最大匹配大小。
首先,最大独立集中任何两个点一定不能由一条边覆盖,因此最小便覆盖不小于最大独立集。
再构造一种方案:选出所有匹配边,再对于所有未匹配点单独选一条和它相连的边,就得到了一组等于最大独立集的边覆盖,因此结论得证。
有向无环图最小路径覆盖
考虑如下问题:给定简单 DAG,我们要选出其中数目最小的不相交的路径,使得每个点至少在一条路径上。
设给定的有向图为
定理:
证明:
考虑建立两者之间的对应关系:
- 对于
G 的一个路径覆盖,对于其中某条路径v_1\to\ldots\to v_m ,在G_0 中选出v_i\to v_{i+1} 的边,因为路径间不相交,所以每个点入度和出度都不超过1 ,因此选出的边构成匹配; - 对于
G_0 中的一组匹配,同上可以构造G 的一个路径覆盖,注意没有边经过的点都视为被一条空路径经过。
在上面的对应过程中,每增加
例题
6 :[CTSC 2008] 祭祀给定简单有向无环图
G=(V,E) ,求最大的A\subseteq V 使得\forall x,y\in A ,不存在x 到y 的路径。
这是一个非常经典的问题。
一个熟知结论是:将 DAG 传递闭包后得到一个偏序集,即如果
根据 Dilworth 定理,偏序集的最长反链长度等于最小链划分大小,在传递闭包 DAG 上即为:如果选出的满足题目条件的点集
因此答案就是传递闭包后的最小路径覆盖大小。
3. 二分图最大权匹配
对于给定二分图
注意,如果给定的
为了求解这个问题,让我们再次借助线性规划工具:
其中
仍旧将它对偶,得到:
我们将对偶问题中的变量
最小顶标和问题:给定二分图,给每个点一个顶标,使得每条边两端点的顶标和不小于边权,且所有点顶标和最小。
不过,再次我们需要做一些补充:
- 在上面的线性规划证明中,我们要求
w_i\ge 0 ,即边权非负。 - 但是,如果存在
w_i<0 ,那么就不能用上面的方法证明(顶标有可能是负数,不满足线性规划的条件),此时我们可以将所有权值加上一个极大数,最后减掉,但这种方法成立的条件是最大权匹配为完美匹配(或至少为最大匹配),下面的 KM 算法本质上也只能解决这种问题。
接下来我们将介绍 KM 算法,KM 算法通过解决最小顶标和问题,可以求出给定二分图的一组权值和最大的完美匹配。
在叙述算法过程前,先说说怎么将原先的问题(最大权匹配)转化成最大权完美匹配:
- 如果要求
w_i\ge 0 的最大权匹配,那么我们只需要将所有不存在的边视为边权为0 的边,如果左右两部点数不相等则补为相等,就转化成了最大权完美匹配问题; - 如果要求存在
w_i<0 的最大权完美匹配(当然也可以是权值都非负的),就将不存在的边权值设为-\infty ; - 如果要求存在
w_i<0 的最大权匹配,那么当然是把所有负权边删掉,变成非负情况。
我们将左部点
相等子图定义为所有满足
命题:相等子图中若存在完美匹配,则这组完美匹配是原图的一个最大权完美匹配。
证明:考虑这组完美匹配的边权和,根据相等子图定义应当是
接下来考虑:如果相等子图中没有完美匹配,尝试通过调整顶标使得相等子图中的最大匹配变大,从而最终形成完美匹配。
假设此时左侧有点
- 对于匹配边,两边必然都访问到或都不访问到,因此
A_i+B_j 不变,仍然属于相等子图; - 对于某个以访问到的左部点为一端的非匹配边,由于
A_i 减小,有可能被新加入相等子图中。
所以这么做不会影响原先匹配,但可以增加新的边进入相等子图,从而继续增广,而我们只要取
于是我们首先任意设定初始合法顶标(如右部点都为
考虑优化这一算法,我们下面介绍一种 slack 优化的基于 BFS 的 KM 算法。
-
在每次加入一个左部点,尝试增广时,模拟匈牙利算法求增广路的过程,而对于右部每个点
y ,记录slack_y 表示这一轮已经访问的左侧点x 中,A_x+B_y-d(x,y) 的最小值。 -
当我们访问到一个左部点时,先用它更新所有右部点的
slack 值,接下来我们取出右部slack 最小的一个点,将其值设为\Delta ,然后将当前已经访问的左部点顶标减小\Delta ,当前已访问的右部点顶标增加\Delta ,并更新slack 数组(实际上就是每个点的slack 也需要减小\Delta )。 -
下一个访问的左部点将是刚才取出的右部点的匹配点,这就是一个寻找增广路的过程,而当那个右部点是非匹配点时,我们已经找到了一条增广路。
-
重复上述过程,依次加入所有左部点,最后就求出了最小顶标和问题的解,也就是最大权完美匹配的方案。
例题
7 :[UVA 1411] Ants给定平面上
n 个黑点和n 个白点,请选n 条线段,每条线段连接一个白点和黑点,每个点只作为一条线段的端点,且这些线段两两不交。
根据简单的初中几何知识,若
所以所求的就是连接黑点和白点的长度和最小的
4. Hall 定理
对于二分图
Hall 定理:设二分图
证明:
必要性:若存在
充分性:若条件成立但不存在大小为
Hall 定理有一个简单的推论:
推论:若一个无向图每个点度数都为
证明:
考虑一个左部点集
Hall 定理还可以用于点带权值的情况,若左部点
我们还可以对此定理进行推广:
Hall 定理推广:设二分图
证明:
令
首先最大匹配不会大于这个数,考虑
随后,若最大匹配小于这个数,考虑从左部所有非匹配点出发尝试增广,类似 Hall 定理的证明,可知所有递归过程构成以所有左部非匹配点为根的,所有叶子为左部点的森林,设左部非匹配点有
例题
8 :给定左部
n 个点,右部m 个点的二分图,左部点i 向右部[l_i,r_i] 内所有点连边,求是否存在大小为n 的匹配。
考虑枚举一个右部点集
所以当不存在大小为
考虑用数据结构维护这一过程,升序扫描
例如,线段树就可以实现这一要求,时间复杂度为
但是之后,我又得知了这题的一种更简单做法,我们接下来继续分析这张图匹配的特性。
把所有左部点按照
根据 Hall 定理,设左部点集为
考虑这种匹配的最优性,若匹配后
因此贪心匹配,每次选取当前点的可匹配点中最靠前的一个没有被匹配过的点,若每个点都能匹配则找到了大小为
这启发我们:Hall 定理可以作为一些显式或隐式匹配问题的贪心策略依据。
例题
9 :给定左部
n 个点,右部m 个点的二分图,左部点i 向右部[1,l_i]\cup [r_i,m] 内所有点连边,求最大匹配。
枚举左部点集
考虑枚举
线段树可以做到
例题
10 :给定左部
n 个点,右部m 个点的二分图,左部点有点权a_i,b_i ,右部点有点权c_j,d_j ,且(i,j) 之间有边当且仅当a_i\ge d_j 或者c_j\ge b_i ,求最大匹配。
考虑左部点
线段树可以做到
5. 网络最大流
给定有向图
令
定义一个合法流函数
-
-
- 令
fl_i=\sum\limits_{j=1}^n f(i,j) ,有fl_s\ge 0,\ fl_t\leq 0 ,对于其他点都有fl_i=0 。
直观理解:从
最大流问题即需要对于给定网络图找出一个合法的流函数,使得
首先让我们证明一些基本性质:
-
- 若不存在
i\to j 和j\to i 的边,则必有f(i,j)=f(j,i)=0 ,这是因为c(i,j)=c(j,i)=0 。
根据第二条性质,我们只需要记录存在边的点对之间的流,更具体地,只需要记录每条边上运载的流的大小。
下面将介绍解决最大流问题最常用的 Dinic 算法(如果想要搞清楚几种网络流算法的本质,复杂度分析和写法,建议去看其他博客,我这里对于算法本身的讲解可能不太行)。
首先确定一个任意的初始流函数,如所有
设当前已有一个流函数
在残量网络上,我们任取一条
各种最大流算法几乎都用到了一个重要性质:当前流函数是最大流,当且仅当残量网络不存在增广路,此结论将在接下来介绍最小割问题后再作证明。
一种暴力的思路:每次找出当前残量网络中的一条增广路(直到不存在增广路),考虑其中
Dinic 算法对此进行了优化,在寻找增广路前,先对残量网络进行了分层,使得
随后我们在增广过程中,只保留出发点的层数比终点层数恰好小
Dinic 算法的优势是一次可多路增广,其中的搜索部分通常采用 DFS 实现,而分层采用 BFS 实现。
Dinic 的一个常见优化是当前弧优化,在 DFS 到一个点时,我们每次都顺序遍历其出边尝试增广,但是一旦一条边的流量已经达到其容量,那么下次就不必再考虑这条边,可以将当前点出边对应的表头指向下一条边。
最大流可以解决二分图最大匹配问题:建立源汇点
例题
11 :[SDOI 2013] 费用流给定网络图,Alice 需要给出一个最大流对应的流函数,随后 Bob 可以给每条边赋予非负费用
c_i ,要求所有边费用总和为P ,使得 Alice 的最大流中所有边的流量乘费用求和最大,Alice 希望这个最大值最小,求这个最大值的最小值。
显然 Bob 会把 Alice 的最大流中流量最大的一条边的费用设为
所以我们二分各边流量的最大值,将所有边的容量对此取
例题
12 :[USACO 07 OPEN] Dining有
n 头牛,f 种食物和d 种饮料,每种食物和饮料只有一份,每头牛有一些喜欢的食物和饮料,求最多有多少头牛可以得到自己喜欢的食物和饮料。
令食物为左侧的点,饮料为右侧的点,牛为中部的点,每个牛向所有喜欢的食物和饮料连边,源点向每种食物连容量为
最大流问题还可以用于解决一些其他模型。
对于有向图
定理:最小割等于将每条边的代价转换成其容量后
证明:
首先将网络图中
接下来我们按如下方法刻画一组割:将
接下来的证明分成三个部分:
-
对
G 中的任意合法流函数,其fl_s 不超过G 的最小割。考虑
L 中所有点的fl 之和,一方面它等于fl_s ,另一方面这里面的所有流量都是从L 到R 的,所以不能超出L 到R 所有边的容量和,即C(L,R) 。 -
最大流对应的残量网络中无增广路。
若有增广路,则还可拓展出更大的流。
-
若一个流对应了无增广路的残量网络,则它也对应了一个不超过其
fl_s 的割。考虑将
L 设为残量网络中s (通过容量为正的边)可达的点集,其余点放在R 中,则L 到R 的边必定都是满流的,所以fl_s 不小于这组割。同时,根据
1 可知,这个流的流量恰好等于割的大小。
由此,我们证明下面三个命题等价:
所以任何最大流可以得到一组最小割,而最小割大小又不小于最大流流量,因此最小割大小等于最大流流量。
同时我们还可以的得到刚才要证的一个结论:无增广路的残量网络必然对应最大流。
因此我们只需求出
这种给定源点汇点的最小割问题称为
例题
13 :[USACO 5.4] Telecowmunication给定无向图
G 和点s,t ,求最少删除多少个非s,t 的点可以使得s 到t 不连通。
按照上一道例题的方法,我们将每个点拆成两个点
注意当我们要求一条边不能被割时,就将代价设为
给定有向图
考虑转化问题,我们可以选择一些点权非负的点,但是需要付出的代价是它们能够到达的所有点权为负的点的点权,这样转化的好处是:如果一个点权为正的点可以到达一个点权为正的点,那么根据和最大的原则,若选了前者则也会选后者。
选择一个点权为负的点相当于把答案减掉它的权值,可以理解成我们需要“舍弃”这个点的权值。
因此我们将问题转化成了类似二分图的问题:将点权非负的点向它能到达的所有点权为负的点连边,再从
- 对于一个点权非负的点,要么干脆不选它,要是选了就得舍弃它能到达的所有点权为负的点的点权;
- 如果不选这个点,就理解成割掉
s 到它的边,而舍弃一个右边的点就理解成割掉它到t 的边,由此,一种选择对应一种割; - 将
s 到点权非负的点的边的代价设为其权值,点权为负的点到t 的边的代价设为其权值的绝对值,其余边代价为+\infty ,用点权非负的所有点的权值和减去s 到t 的最小割即为答案。
在熟悉最大流后,下面集中讨论一些二分图和网络流问题中构造方案以及所有方案的交并的问题。
最大流方案
做完 Dinic 算法外我们已经得到了每条边的流量,这就是一种方案。
最小割方案与可行边必经边
根据我们证明最大流最小割定理时所用的方法,求出最大流后顺便(在最后一次不成功的 BFS 中)算出当前残量网络中
最小割可行边定义为存在一种最小割使得这条边被割断,必经边定义为每个最小割中这条边都被割断。
首先考虑简单的判断,设原图为
- 此边是可行边,当且仅当图
G 中删除这条边(代价改为0 )后的图的最小割减少了w ; - 此边是必经边,当且仅当图
G 中把这条边代价改为+\infty 后的图的最小割变大。
但是这样似乎并不够快,在
命题:一条边
证明:
- 如果这条边不满流,那么直接删掉这条边,退掉
s\to u 和v\to t 的等量的流,整个网络的流量减少了这条边的当前流量,不到w ,根据上面的结论这不是可行边; - 如果存在
u\to v 的路径,那么删除这条边后还能找到s\to u\to v\to t 的增广路,故最大流减少了不到w ,根据上面的结论这不是可行边; - 如果这条边满流且不存在
u\to v 的路径,则删除这条边后仍然不存在s\to t 的增广路,故最大流减少了恰好w 。
命题:一条边
证明:
- 如果这条边不满流,那么直接按照之前说的方案构造一组最小割,就不会包含这条边;
- 如果
G' 中不存在s\to u 的路径,那么加大这条边的容量,因为找不到s\to u 的路径,所以最大流不会变大,从而最小割也不会变大,根据上面的结论不是必经边; - 如果
G' 中不存在v\to t 的路径,同理; - 如果这些条件都满足,那么将这条边的容量改为
+\infty 后可以找到s\to u\to v\to t 的增广路,从而最小割增大,这是必经边。
下面归纳一下这两个命题,并给出一种实现方法:
定理:将
证明:以下都设探讨的边满流。
假设存在
因此对于满流边
假设存在
因此对于满流边
因此命题得证。
现在可以试探讨最小割方案的结构:将
二分图最大匹配方案与可行边(点)必经边(点)
二分图最大匹配方案可以用网络流或匈牙利算法直接求出,接下来考虑求可行边与必经边。
定义:如果一条路径依次通过非匹配边和匹配边,首尾分别是匹配边和非匹配边,并且终点是非匹配点,那么就称这是一条半增广路。
定义:如果一个简单环依次通过非匹配边和匹配边,那么就称这是一条增广环。
考虑半增广路和增广环的实际意义:如果我们将半增广路或增广环上所有边的状态(是否是匹配边)取反,可以得到一个新的最大匹配。
并且倒过来也可以成立:
定理:对于任意两组最大匹配
证明:类似证明无增广路等价于最大匹配的思路,我们求出两个匹配的对称差的导出子图
由于
长度为奇数的链是不可能存在的——否则这就是其中一个匹配(这条链首尾不属于的那个匹配)的一条增广路。
因此只有偶链和环,而它们就分别是上面所说的半增广路和增广环,将它们分别取反即可从
接下来将这一结论运用到求可行边与必经边上来,首先任求一个最大匹配
命题:边
证明:
- 如果
(u,v) 属于当前最大匹配,那么毋庸置疑其是一条可行边。 - 如果
(u,v) 不属于当前最大匹配但存在经过(u,v) 的半增广路或增广环,将之取反即得到一组包含(u,v) 的匹配。 - 如果
(u,v) 不属于当前最大匹配且不存在经过(u,v) 的半增广路和增广环,假设存在最大匹配P' 包含(u,v) ,则P\Delta P' 中没有任何一条包含(u,v) 的增广路,半增广路和增广环,这是不可能的。
命题:边
证明:
- 如果
(u,v) 不属于当前最大匹配,那么当然不是必经边。 - 如果
(u,v) 属于当前最大匹配但有一条经过它的半增广路或增广环,将之取反即得到不包含(u,v) 的匹配。 - 如果
(u,v) 属于当前最大匹配且没有经过它的半增广路或增广环,假设存在最大匹配P' 不包含(u,v) ,则P\Delta P' 中没有任何一条包含(u,v) 的增广路,半增广路和增广环,这是不可能的。
在更进一步之前,我们先考虑将半增广路也转换成增广环,考虑到半增广路的两端分别是匹配点和非匹配点,我们模仿网络流求解二分图时那样进行如下建图:
- 建立源点
s 和汇点t ,从s 向左部非匹配点连边,左部匹配点向s 连边;从t 向右部匹配点连边,右部非匹配点向t 连边; - 对于原二分图中的边,如果属于当前最大匹配,就从右部点连向左部点,否则就从左部点连向右部点。
考虑新图,一条不经过
再考虑经过
所以在新的有向图
那么我们可以将上面的命题整理:
定理:边
值得一提的是,上面的
Bonus:二分图最大匹配可行点?
任何度数不为
Bonus:二分图最大匹配必经点?
仿照上面的结论,只要不存在以这个点为端点的半增广路,也就是不存在包含它到
6. 最小费用最大流
给定一张网络图,每对点除容量
请注意,我们下面讨论的是价值函数不构成负圈的网络图上的费用流问题,而有负圈的情形将在介绍上下界网络流后说明。
首先我们补充一下残量网络的定义:残量网络中每条反向边价值为正向边的相反数,这符合反悔的实际意义。
令
-
令
F_0=0 ; -
在第
i 轮,以价值为边权,找出当前残量网络上s\to t 的最短路,将其附上1 的流,并令F_i=F_{i-1}+l ,其中l 是这条路径上所有边价值和。
下面简要地证明其正确性:
归纳证明,当
当
如此,我们需要寻找
答案是肯定的,我们有:
命题:在
证明:
假设不是,那么只能是
设其中第一条这样的反向边为
有了这一命题,我们只要找到一条最短路,就可以连续增广
关于最短路,我们可以直接使用 Bellman-Ford 进行求解。
但也有另一种选择,考虑 Dijkstra 不能直接做的原因:残量网络中可能存在负权边。
那么我们只需要仿照 Johnson 算法,为每个点赋一个势
-
初始时可以用单次 Bellman-Ford 算出初始势,随后我们在每次求解最短路后更新势:
-
每次的新势本应等于上一次的最短路,但是由于上一次的最短路是带着势算出的,所以我们应在原本的势上累加这个最短路,即每次令
h'_u\leftarrow h_u+dis_u 。
这样,Dijkstra 也可以用于求解费用流问题了。
上述的费用流算法称为 SSP(Successive Shortest Path)算法,该算法不仅可以求最大流时的最小费用,而且可以求出流量依次为
当要求最大费用时,只需将边权取反并求最小费用即可,而存在负环的最小费用流可以利用后面的上下界网络流解决。
费用流可以用于解决二分图最大权最大匹配,只需将最大流求最大匹配时中间的边附上权值作为价值即可,但其复杂度比 KM 算法高,一般不推荐使用(费用流可以求解大小为
例题
14 :[ZJOI 2010] 网络扩容(第二问)给定一个网络图,每条边有费用
w(u,v) ,表示让u\to v 的容量加1 需要付出w(u,v) 的代价,求使得1\to n 最大流增大k 的最小代价。
新算出最大流
对于原图中每条边
新图的最小费用最大流即答案,注意只要
有一类费用流问题由于图的特殊性,可以使用一类特殊贪心来解决,这种方法通常称为模拟费用流。
由于作者认为模拟费用流和网络流关系较小,所以这里仅稍作提及,也主要是讲和流有关的部分。
费用流这种每次选取一条最短路进行增广的想法让我们联想到贪心,但保证费用流正确性的是其反悔机制——反向边用于退掉之前更劣的流,因此我们考虑在贪心中也贯彻这一点。
例题
15 :[NEERC 2016] Mole Tunnels给定
n 个点的完全二叉树,点i 有c_i 份食物,接下来依次来了m 个鼹鼠,第i 个鼹鼠出现在点p_i ,每个鼹鼠要到一个点去,使得每个点的食物数不小于待在这里的鼹鼠数,对每个i\leq m 计算只考虑前i 只鼹鼠的最小移动总距离。
考虑费用流建图:
从源点向每个鼹鼠所在点建容量为
下面用贪心来模拟费用流过程:
考虑按照输入的鼹鼠顺序进行增广,按照最短路原则,对于每个鼹鼠都找到当前残量网络中离它最近的那个有食物的点钻进去就行了。
如下图过程,图中非源汇的点中的数字表示当前食物数量,它们之间的黑边表示价值为
第一个鼹鼠来到根结点,首先找到离它最近的有食物的点(找到了最右边的点),然后走这条流,经过的树边由于有了流量,所以残量网络上就有了反向边(蓝边),代价为
第二个鼹鼠来到根结点右儿子,此时只有最左边的点有食物,它可以跑过去,途经的价值和为
考虑蓝边的实际意义:当第二个鼹鼠来之后,我们发现第一个鼹鼠的决策错误了,应该第一个鼹鼠到左边,第二个到右边才是最优的,所以蓝边给我们提供了一次后悔机会——如果把原来第一个鼹鼠走的那段路换成第二个鼹鼠的,那么这条边就可以退掉了。
由此可以考虑贪心:对于每个鼹鼠都找当前树上离它最近的一个有食物的点,答案增加这条路径的长度,将那个点的食物数量减少
由于完全二叉树的树高为
例题
16 :种树有
n 个排成一排的坑,要在其中恰好m 个坑里种树,使得不存在两个相邻的坑都有树,每个坑有个美观度A_i ,求种上树的坑的美观度之和的最大值。O((n+m)\log n)
设在坑
因此可以建出一个二分图最大权匹配的模型:以编号为奇数的位置为左部,偶数的位置为右部,
可以发现,一条增广路肯定是由一个区间内的坑构成的,相当于我们每次行完一条流,就把三条边合并为了一条边(作为增广路是一个整体),如图:
而这个等效边的流量,相当于原来两侧的坑的美观度减掉中间的坑的美观度(因为中间的是反向边)。
因此贪心策略就明显了:每次选择当前美观度最大的坑
用堆维护,时间复杂度为
例题
17 :[CF 280 D] k-Maximum Subsequence Sum维护一个序列
A ,q 次操作和查询,包括单点修改和询问:从区间[l,r] 中选出至多k 个不交子区间的最大元素总和。
考虑给定一个序列,询问
费用流建图,从
这个问题中的反悔非常容易理解:就是把选了的区间中的数都改成相反数,这样以后取到的时候表示去掉这个部分。
所以这题的贪心策略也非常显然了:每次选择和最大的子段,将其和加入答案,并将这个区间取反,连续做
利用线段树维护上述操作,时间复杂度为
例题
18 :[NOI 2019] 序列给定两个长度为
n 的序列a,b ,请从中各选出K 个下标,使得至少L 个下标在两个序列里都被选,且两个序列中各自选到的下标对应的数之和最大。
首先考虑用费用流解决:
如图,
走红边表示不同的下标,走蓝边表示相同的下标,这些边的价值都为
下面我们将这个问题中的流分成以下这些类型:
-
自由流:形如
s\to a\to m\to M\to B\to t 的流; -
限制流:形如
s\to a\to A\to t 的流; -
反悔流:形如
s\to a\to A\to M\to C\to t 的流。这样的流如何产生呢?见下图(省去了连向
m,M 的无用边) ,我们首先流了一次b\to A 的自由流,然后现在就有了A\to M 的反向反悔边,所以我们可以利用这条边反悔b\to A 的匹配,改成一个b\to C ,这样A 就可以与a 匹配,不改变m\to M 的流量而进行了一次反悔。注意这样的反悔有两种,一种是上面说的,还有一种是形如
s\to a\to m\to c\to C\to t ,即经过m 进行一次反悔; -
假自由流:形如
m\to a\to A\to M 的流。见下图(省去了连向
m,M 的无用边),我们首先流了两条自由流a\to C 和b\to A ,随后发现如果我们把a\to A\to M\to m\to a 这个环上的一条流退掉,就会使自由流的容量增大1 ,下次要流自由流的时候就不用走m\to M ,而是可以借道a\to A 。本质上,这种流的作用是把
a\to C,\ b\to A 换成了a\to A,\ b\to C ,使得用掉的自由流变少了。
所以我们在贪心中有如下这些对应的决策:
- 选择当前最大的一对没有流过的
a_i,b_j ,如果i=j 则流限制流,否则流自由流; - 选择当前最大的两边都没流过的
a_i+b_i ,流一条限制流; - 选择当前
b_i 已经流过的a_i 的最大值,以及当前还没流过的b_j 的最大值,在它们之间流一条反悔流; - 选择当前
a_i 已经流过的b_i 的最大值,以及当前还没流过的a_i 的最大值,在它们之间流一条反悔流; - 每次建立一条流后,都检查是否存在假自由流(环),如果存在就退掉这环上的一条流。
我们只需要记录当前自由流的剩余流量,当选择一条自由流时流量减少
注意当某些决策同样优时,选择能增大自由流剩余流量的。
时间复杂度为
7. 上下界网络流
现在将网络图的定义做一些调整,除了流量上限(容量)
上下界网络流还可以按一些标准分类:
- 无源汇和有源汇:因为有了上下界,有些题目中可以只保留流量守恒的限制,而没有源汇点
s,t ,这类问题是无源汇上下界网络流问题; - 可行流,最大流,最小流,费用流等。
本篇中基本都会提到这些类问题。
无源汇上下界可行流
最基础的上下界网络流问题:给定一张上下界网络图,求一种合法的流量函数,使得每个点都满足流量守恒。
考虑将问题转化成无下界的,我们熟悉的网络流问题。
首先我们强制每条边都要流到下界,即
对于一个
对于一个
因此,我们新建超级源汇
根据
有源汇上下界可行流
上一个问题略微修改一下:给定一张有源点汇点的上下界网络图,求一种合法的流量函数。
考虑将问题转化成无源汇上下界可行流。
有源汇和无源汇的区别不过在于
有源汇上下界最大流
首先求一次有源汇上下界可行流,假如不存在则无解。
记录
因为现在和
另一思路:二分答案
有源汇上下界最小流
同上先求可行流,记录当前
原来我们要求最大流,不断从
更本质地说,用当前流量减掉残量网络上
同最大流,也可以二分答案来做。
无源汇上下界最小费用可行流
按照无源汇上下界可行流同样建图,新增的边价值为
先将初始费用设为
有源汇上下界最小费用流
关于有源汇上下界最小费用可行流,就是连边
而如果是最小费用最大流,其实也一样,跑完
这里最大流改成最小流,最小费用改成最大费用也都一样,只是前面各种 trick 的互相组合,这里不再赘述。
有负环的费用流
对于一条价值为负数的边
但是这有一个问题,现在的
如果原问题无源汇,那么现在就是个
例题
19 :[Luogu P4843] 清理雪道给定 DAG,求最少需要几条路径能覆盖所有边至少一次。
类似于前面说的最小路径覆盖,只是现在可以交了,仍然可以用网络流模型解决。
对于每一条路径
这样将覆盖转化为下界的思路比较通用。
8. 网络流扩展与建模举例
首先我们介绍一些网络流建模问题中的常见想法与转化:
-
多源汇问题:
如果一道题中有多个可行的源点
s_1,\ldots,s_a 和多个可行的汇点t_1,\ldots,t_b ,那么我们可以建立超级源汇S,T ,从S 向s_i 连容量无穷的边,t_i 向T 连容量无穷的边,转化成单源汇的问题; -
点转边:
如果一道题有诸如“一个点只能有不超过
f 的流经过”之类关于点的限制,可以将每个点拆成两个点(分别为入点和出点),连入边统一连到入点,连出边统一从出点连出,随后在入点和出点中间连一条和f 有关的边; -
边转点:
在一些特殊问题中(不一定是网络流),需要将边转化成点,可以考虑为每个边新建一个点,向两端连边;
-
出入流量差限制:
如果在网络图中对某些点
i 要求其出流量减去入流量恰好等于f_i ,那么就按照上下界网络流类似的方法,建立超级源汇,对于f_i>0 的点从S 向它连边,否则从它向T 连边,容量为|f_i| ,随后要加上S 或T 的相关边满流的限制; -
双选问题:
如果一道题中某个元素有两种(或多种)可能的取值,那么可以先假设取其中一个代表(例如,最小值),再用流标记调整(要改成较大的)。
本篇参考资料:
https://www.luogu.com.cn/training/9385
https://www.luogu.com.cn/training/9386
https://www.luogu.com.cn/blog/command-block/wang-lao-liu-xiang-guan-bi-ji
前两者题目较为基础,后者题目量大,本篇例题大半来源于此,这里主要抽取一些有代表性和有多道相似性高的题目。
当然,为了确保自己对网络流这部分的各种技巧都比较熟悉,可以把 command_block 博客中的所有题都口胡一遍(我就是这么做的),目标是绝大部分题目都能在较短时间内出解法。
此部分尚不完善,后续可能会来补充一下。
最大流建模
单纯的最大流比较少见(基本都有和其他技巧的融合),所以这里就随便列举两题。
例题
20 :[网络流 24 题] 最长不下降子序列问题(第二问)给出一个长度为
n 的序列a_{1\ldots n} ,求最多能选出几个不相交的最长不下降子序列。
这道题可以从分层图的角度考虑。
首先求出
用一条流来刻画一个最长不下降子序列,考虑怎样的子序列
- 只要满足
f(b_{i+1})=f(b_i)+1 ,且f(b_1)=1 ,而m 恰是最长不下降子序列长度。
设最长不下降子序列长度为
最后从源点向第一层点连边,最后一层点向汇点连边,最大流即为答案。
按照同样的思想,我们还可以求给定图中起点到终点的边/点不交最短路最大数量,只需要考虑最短路 DAG 即可。
例题
21 :[CQOI 2014] 危桥给定无向图,两个人分别要走
2\times a_n 次a_1\to a_2 的任意路径和2\times b_n 次b_1\to b_2 的任意路径,某些边可以任意多次经过,某些边只能经过两次,求是否存在合法方案。
一个十分奇怪的问题。
结论:第一次设置源点为
证明:容易证明两次最大流中
某些题解中还讨论了是否会有一条边被正反都走过的问题,实际上是不必要的,最大流的正反边不会都有有意义的流。
最小割建模
直接的最小割:
例题
22 :[ZJOI 2009] 狼和羊的故事给定
n\times m 网格中每个格子有狼,有羊,或者都没有的状态,求周长总和最小的一些边线,使得任意一狼无法在不经过这些边线的情况下走到任意一羊处。
将每个狼都视为源点,每个羊都视为汇点,一条边线是隔断代价为
除了这种比较显然的问题外,一般在考虑最小割建图时,我们会利用其二元性——一个点与
最小割模型
1 (双选模型):有
n 个物品,需要将它们分为 A,B 两个集合,第i 个物品分入 A 集合的代价是a_i ,分入 B 集合的代价是b_i ,对于i,j 两个物品如果它们所属集合不同则需额外付出c_{i,j} 代价,求最小总代价。
将每个物品建点,令与
首先从
对于
图的最小割即为答案。
此图的点数为
上述模型的一些简单变形:
- 某个物品最初属于其中一个集合,换到另一个集合需要代价
d_i :那么分入原来集合的代价就是0 ,不建对应的边即可; - 只有
i 属于 A 集合且j 属于 B 集合才需要付出c_{i,j} 的代价:双向边改成单向边;
例题
23 :[SHOI 2007] 善意的投票 / [JLOI 2010] 冠军调查有
n 个小朋友,每个小朋友有个0/1 值,要取反一个小朋友的值需要1 的代价,有m 对小朋友是好朋友,如果它们的值不一样则需要付出1 的代价,求最小总代价。
第
例题
24 :[SDOI 2016] 墙上的句子较复杂,详见题面。
首先解决掉回文串——它们一定会计入答案,接下来只考虑非回文串。
对于每行每列分别建点,与
对于已经确定正反的串,当然我们直接将它与
对于两个串的联合贡献,是一些单词的集合,我们从字典序比反串小的单词向其反串间连一条容量为
如果一行或一列不知道应该放在
注意上述模型的使用限制:
- 每个元素的决策必然是二元的(最小割中只有和
s,t 连通两个选择); - 联合贡献只能是两个元素之间的(一条边只有两个端点);
- 联合贡献对答案是负影响(也就是要这样的贡献越少越好,对应最小割)。
如果上述第二或第三个条件不满足,则需要用到最大权闭合子图的建图方法,通常情况下点数会增大为联合贡献的个数。
最小割模型
2 (串联模型):有
n 个[1,m] 中的数a_1,\ldots,a_n (不是给定的),将a_i 赋值为j 则需要付出v_{i,j} 的代价,有q 个限制,每个限制形如a_x-a_y<z (可改变不等号方向)。
将每个数
接下来考虑一个条件
但是注意,现在的最小割不一定每条链只割了一条边,为了保证不会有一条链通过割掉多条边满足不同的约束,所以我们可以先将约束求一遍最短路,对每一对点列建边。
比较简单且边数较少的方法是建边
图中的点数
简单变形:
- 将
a_i 赋值为j 可以获得收益:先加上最大收益,再将每个数的收益与最大收益的差作为代价。 - 不等号方向改变:
a_y-a_x<-z 。
例题
25 :[HNOI 2013] 切糕给定所有
v(x,y,z)\ (x\in [1,P],y\in [1,Q],z\in [1,R]) ,求一组f(x,y) 使得相邻的(|x_1-x_2|+|y_1-y_2|=1 )二元组的f 值差不超过D ,且所有v(x,y,f(x,y)) 之和最大。
考虑直接建立费用流模型,每个点的一条流费用为
所以这题的反悔贪心似乎不能用费用流解释......
这题的解法(贪心和凸函数卷积(?))暂时留坑。
例题
35 :[WC 2007] 石头剪刀布给一张已部分定向的竞赛图定向,使得三元环最多。
考虑怎样的三个点不构成三元环:必然有恰好一个点向另外两个点都有边,恰好一个点向另外两个点都没有边,所以非三元环的个数就是
想要非三元环最少,考虑对一条边定向为
对于所有未确定的边建点,向两个端点各连一条边,并从
每个点向
这个模型的意义是:未定向边出去的流量表示边指向的方向,指向一个点就会使得其
由于上面的费用关于
图覆盖模型:
给出一些条件,要求用一些链或圈覆盖图的所有点。
通常我们可以用二分图模型来描述这类问题,下面整理一下:
-
DAG 不相交路径覆盖:拆点建立二分图,如果有边
x\to y 则从左部点x 向右部点y 连边,一个匹配就对应一个不相交路径覆盖,其中匹配边x\to y 表示x,y 是一条路径上的前驱后继关系。为什么只能做 DAG?因为若不是 DAG 这里就会成环,就不是不相交路径覆盖了。
- 最少路径的不相交路径覆盖:前面讲过,和最大匹配对应;
- 最大权不相交路径覆盖:求最大权二分图匹配。
-
DAG 可相交路径覆盖:先传递闭包得到新 DAG
G' ,容易发现原图的可相交路径覆盖对应G' 的不相交路径覆盖。 -
不相交圈覆盖:给定一张任意有向图,仍然和上面一样建立二分图,每一组完美匹配就对应一个圈覆盖,左部点
i 的匹配点就是其圈上的后继。- 最小/大权不相交圈覆盖:求最小/大权二分图匹配。
例题
36 :[洛谷 2020 2 月月赛 I] [加油武汉] 疫情调查给定有向带权图,每次你可以选择一个非空回路,付出其权值和的代价以覆盖其中一个子集,也可以选择一个点
u 付出a_u 的代价覆盖这个点,求覆盖所有点的最小总代价。
容易发现选择回路覆盖子集的代价就是选出的所有相邻点对最短路之和。
所以建立新图,从
直接使用 KM 算法就行了,但是也有种费用流的做法:我们无需计算最短路,拆点后从
采用这种建图,当图的点数和边数相差不大时,费用流效率可与 KM 打平。
例题
37 :[ZJOI 2011] 营救皮卡丘有
n+1 个点(0 到n 编号)的有向带权图,k 个人从0 出发,每个人每次只能走到编号不超过之前走到过的最大编号加1 的点,每个点要至少被一个人走过,问最小的所有人走过的边权和之和。
假设现在已经走过了
随后可以发现,我们只是要用
当一道题限定了一个点或一条边的流量时,使用上下界网络流解决问题。
如果一个点不满足流量守恒,可以使用类似上下界网络流的处理手法,建立超级源汇解决问题。
例题
38 :[Luogu P4553] 80 人环游世界用
k 条路径覆盖一个 DAG,第i 个点恰好经过V_i 次。
直接建图,每个点都拆成两个点,限制其间流量为
这个办法也可以直接解决不相交路径覆盖,但是没有二分图匹配那么简易。
例题
39 :[CF 708 D] Incorrect Flow给定一张网络图和其流函数,不一定满足
f(u,v)\leq c(u,v) 和流量守恒,每次操作可以增大或减小一个f(u,v) 或c(u,v) ,求最小操作次数,使得流函数合法。
考虑改变一条边流量的代价:
-
退流,反向边,容量为 $f(u,v)$,费用为 $1$(只需要将 $f$ 减小); 增广而不到原 $c(u,v)$,正向边,容量为 $c(u,v)-f(u,v)$,费用为 $1$(只需要将 $f$ 增大); 增广超过原 $c(u,v)$,正向边,容量无穷,费用为 $2$(需要将 $f,c$ 同时增大); -
因为这里有个初始修正代价,所以预先加上个 $c(u,v)-f(u,v)$。 增广,正向边,容量无穷,费用为 $2$; 退流不小于 $c(u,v)$,反向边,容量为 $f(u,v)-c(u,v)$,费用为 $0$(一增一减等于不变); 退流小于 $c(u,v)$,反向边,容量为 $c(u,v)$,费用为 $1$。
再注意流量守恒的限制,相当于新增的流不满足流量守恒,而是每个点的出入流量差等于定值,按照上下界网络流类似的技巧建立超级源汇即可。
下面是几道费用流或带权匹配的杂题:
例题
40 :[清华集训 2017] 无限之环较复杂,见原题面。
将两个接头相接处赋予
具体建图时,将每个格子拆成一个主点和四个方向插头,相邻格子就在相向的方向插头间连容量为
为了有源有汇,黑白染色,
接下来只要考虑主点和插头如何连边:
- 对于只有一个接头的”死胡同“水管,主点向四个方向插头都连容量为
1 的边,初始插头的边费用为0 ,垂直的两个方向费用为1 (转一次),相对方向费用为2 (转两次); - 对于 L 形水管,初始两个方向费用为
0 ,然后可以发现,旋转一次就是将一个初始方向插头的流转移到相反方向去,所以从两个初始方向插头分别向相对方向插头连一条费用为1 的边; - 对于卜字形水管,旋转一次可以将原本直线方向的两个插头分一个给原本没有插头的方向,连费用为
1 的边,还可以花费2 的费用翻转,因此另一个插头给其相对插头费用为2 的边; - 十字型水管无需旋转,直线型水管不能旋转,直接从主点连边。
最小费用最大流的费用即为答案。
例题
41 :[SDOI 2013] 刺客信条给定一棵
n 个点的无根树和一个长度为n 的01 串,以及一个长度为n 的目标01 串,每次操作可以翻转当前01 串的一位,最终要使得存在一种树的自同构排列,使得排列后当前01 串变成目标串。
考虑递归,以重心为根,要求各子树进行同构匹配。
设
首先求出其子树的所有同构等价类,递归求
最终自同构即根结点子树到根结点子树的映射。
上面讲了一些比较有针对性的建图技巧。
下面基本上就是一些比较通用的思路了。
优化建图
例题
42 :[TJOI 2011] 卡片有一个二分图,左右分别
n,m 个点,一个左部点和一个右部点有边当且仅当点权不互素,求最大匹配。
普通建图,边数为
例题
43 :[SNOI 2019] 通信有
n 个点排成一列,对于权值为a_i 的i 点或者选择支付w 的代价,或者选择一个j<i 然后支付|a_i-a_j| 的代价,每个j 只能被选择一次,求最小代价和。
对于支付
边数是
拆贡献
例题
44 :[NOI 2012] 美食节 / [SCOI 2007] 修车有
n 种菜和m 个厨师,第i 个厨师做第j 种菜时间为t_{i,j} ,第i 种菜有p_i 个同学想要,每个厨师同时只能做一道菜,问所有同学的最小等待时间和。
假设厨师
所以将每个厨师
注意此题中无用点数很多,一个显而易见的优化是:第一次增广中源点只需要向每个厨师的最后一道菜连边,然后看增广后哪个厨师有流量,就再加源点到它的倒数第二道菜的边,以此类推,点数就被控制在
这里其实也是一个考虑凸性的思想。
例题
45 :[ZJOI 2010] 贪吃的老鼠有
n 个奶酪和m 个老鼠,第i 个奶酪大小p_i ,第i 个老鼠吃奶酪速度v_i ,同一时刻一个老鼠只能吃一个奶酪,一个奶酪只能被一个老鼠吃,每个奶酪有出现的时间区间[l_i,r_i] ,现在可以将所有r_i 都增加一个量,求最少要增加多少可以使得所有奶酪都被吃完。
二分答案,考虑判定。
按照所有奶酪出现时间区间的端点离散化
直接这么连有问题,有可能一个奶酪在同一时间会被多个老鼠吃,如果再将奶酪拆成每个时间段,也不太容易处理。
此时考虑一种神奇的建图方法:
- 首先将老鼠的速度排序后差分,设第
i 个老鼠速度为\sum\limits_{j=1}^i u_j ; - 在每个时间段,对每个
u_i 建点,与每个奶酪连权值为u_i\times tim 容量的边(tim 是时间长度),这样一个奶酪出边最多也只有\sum u_i\times tim ,不会超过最多老鼠的消耗量; - 每个
u_i 对应的点向汇点连u_i\times (m-i+1)\times tim 容量的边,相当于限制了每个值域前缀的总消耗量。
然后再求最大流,就可以得到二分答案后的正确结果了。
9. 本篇后续加工方向
- 网络流和线性规划的关系(Cow and Exercise);
- 平面图最小割=对偶图最短路(狼抓兔子);
- 最大流和费用流的优化和复杂度分析(这个基本没用,有点懒得搞);