网络流,就是一张有向图中给每一边分配一个容量,流可以沿着有容量的边移动。对一个给定的网络,其一个可行流为从源点到汇点的一种流量方案。
网络流问题就是解决最大流、可行流、费用流等抽象问题的一种模型。对一个可行流来说,它有如下特性:
- 除了源汇点外,每一个点的入流与出流相等
- 经过每条边的流量不超过该边容量上限
则最大流就是到达汇点的流量最多的一个可行流,它也满足上述性质。
## 最大流
求最大流可以采用 Dinic、SAP、ISAP 等算法,但我们主要介绍 Dinic。Dinic 算法分为寻找分层图与增广两个部分。下面不加解释地放上 Dinic 的代码:
1 | struct Dinic{ |
上述代码用残量表示边的流量数据。对这份代码的解释很容易在网络上找到,在此不做赘述,而只点出实际写时的易错点:
- 寻找分层图时,不能经过残量为 0 的边。
- 利用当前弧结构保存时,每一次寻找增广路前要清零。并且寻找增广路时要使用引用来更新当前弧。
- 寻找增广路时要对当前边进行修改,因此要对边使用引用而不能单纯复制内容
- 对边的四个操作要保证修改的对象和数值是否正确
- 如果流量为 double 类型,需要 DCmp 判断是否为 0,而不能直接与 0 比较
这是一些很 naive 且很容易忘记的错误。放出以警示自己。
### 带上下界的流
带上界的流一般都采用拆点的方式建图来保证其上下界功能。考虑好必须经过的流量是哪些,可以经过的流量是哪些。
#### 带上下界可行流
##### 无源汇
对于 $E = (u , v)
- 没有下界:普通的网络流,从
向 连容量为 的边。 - 没有上界:
节点必须输出 流量, 节点必须流入 流量。根据这个条件,可以考虑从 向 连流量为 的边,从 向 连流量为 的边,这样就满足了上述条件。
我们发现这两个不互相干扰,一起使用即可。明显,整个网络拥有一个可行流的等价条件是,新增的下界边都满流,否则没有可行流。
由于新网络入流与出流相等,而无源汇的网络满足流量平衡,因此 s 的出流等于 t 的入流,也就满足了新增加的边如果从
##### 有源汇
从
#### 有源汇带上下界最大流
##### 普通做法
我们的立足点是无源汇上下界可行流的求法,因此考虑把有源汇先转成无源汇。按照无源汇可行流的方法建图并跑最大流,得到的是一个原图的可行流,此时的下界应该是填满的(显然,不填满就连可行流都没有)。在残余网络上从原图的
##### 二分做法
我们仍转换为无源汇,但是设从
#### 带上下界最小流
如果不带上下界,则最小流就是零流,没有什么好求的。
##### 普通做法
考虑转化为无源汇,但这次我们不连接从
##### 二分做法
我们仍转换为无源汇,但是设从
#### 总结
我们所有上下界流的基础都是建立在上下界无源汇可行流上,因此这个模型的转换是很重要的。另外,上下界最大 / 最小流的二分解法虽然比普通解法多出一个
## 最小割
流网络 $ G = (V , E)
注意边集中方向为
最小割拥有一些不错的性质:
- 最小割将点集分割成两个部分,且最小割只包含了两端点属于不同点集的边的容量
- 最大流最小割定理:一个网络中的最大流等于最小割
第二个性质很重要,它给了我们一个求最小割的方法。而第一个性质给了我们一个转换模型的思路。我们给出如下性质:
- 最小割一定是最大流中的满流边,但满流边不一定是最小割中的边
这个性质的反例可以在论文中找到。因此寻找最小割边时,需要从源点 DFS 顺着有残量的边遍历,则两端点只被遍历一个的边为最小割边。注意这个有残量的边包括网络中的反边,有些点可能能从反边被到达,因此需要 DFS 而不能单独认为满流边就是最小割边。
### 平面图最小割
可以参考论文《两极相通 —— 浅析最大 — 最小定理在信息学竞赛中的应用》周冬。
平面图的对偶图:把平面图的面当点,连接两个面的边当两个点的边的图。平面图有不错的性质:
- 欧拉公式:顶点数 $ +
- = 2$ - 平面图的对偶图也是一个平面图
对一个源汇点都在无界面的边界的网络,如何根据平面图求它的最小割?我们从
我们得到一个感受:当原问题不好入手时,考虑它的对偶问题。
### 最大权闭合图
这类题目是求具有依赖关系的最大权子图:选择 A 会有一定权值,但同时要选择 B 和 C,它们也会产生权值,这样的关系构成一张有向图。选择有向图的一个子图,使得若
对这类题目的详解在论文有。此处只阐明算法:
- 对原图的所有边容量赋为
- 从
向正权点连权值为 的边 - 从负权点向
链权值为 的边 - 最大权闭合子图 = 正权点权和 - 新图最小割
## 二分图最大匹配
二分图本身就有一个两端属于不同点集的边集,因此二分图常常被询问最大匹配。最大匹配即,选定一个边集,使得边集中的所有点不相交。二分图的最大匹配有
不加注释地给出匈牙利算法代码:
1 | bool vst[N];int lnk[N]; |
这个算法给出的是邻接矩阵做法,我们可以很轻易地改为邻接表。需要注意的点:
- 每次开始搜索前,清空访问数组
- 只有没有访问的节点可以操作
## 图的性质
明确以下概念:
- 点相关
- 最小点覆盖
- 最大独立集
- 最小点权覆盖
- 最大点权独立集
- 边相关
- 最小边覆盖
- 最大匹配
这些概念都可以在论文中找到具体定义,但我们重点讨论它们的性质:
- 最大匹配数
最小边覆盖数 顶点数(条件:联通图) - 最大独立集
最小点覆盖数 顶点数 - König 定理:最大匹配数
最小点覆盖(条件:二分图) - 最大流
最小割 - 最小割
最小点权覆盖集(条件:二分图) - 最小点权覆盖集数
最大点权独立集数 顶点数(条件:二分图)
大部分性质都可以概括为:最值 $ =
## 最小费用最大流
给网络中的每一个边一条边权,求使得最大流的情况下的最小费用。下面不加注释地给出代码:
1 | struct Dinic{ |
要点:
- 增广过程与 SPFA 相似,但仍要注意只有有残量的边可以通过。
- SPFA 过程注意是否出队入队,是否取消标记,是否入对位置正确。
### 费用流拆边
一条边所花费的费用是随流量线性增长。如果呈二次增长,甚至三次增长呢?需要拆边。
假设 $f
### 带权二分图匹配
如果有权,则可以给边赋权用费用流求解匹配。从
## 练习
### 最大流
####USACO4.2.1 草地排水
最大流模板题目。
####BSOJ1721 上下界可行流 & BSOJ1723 上下界最大流 & BSOJ1725 上下界最小流
上下界网络流的练习题。
####BSOJ2547 网络流 24 题 - 6 最长递增子序列
第二问可以考虑每个点只能被选一次,并且假设当前节点结尾的 LIS 为 $ d
####SDOI2015 星际战争
二分答案判断最大流是否足够。注意精度。
### 二分图最大匹配
####SCOI2015 小凸玩矩阵
二分答案
####USACO2005NovGold Asteroids
有行星的位置连接一条边,求最小点覆盖。可转化为最大匹配。
####USACO2005JanGold 泥泞的牧场
注意到每个点只能被横行或纵列覆盖(可以同时覆盖)。对于连续的泥泞,我们一块木板盖上是最好的。因此我们可以把图分块。横向的分块与纵向的分块编号后,一个泥泞就只能对应一条横向与一条纵向分块的交点了。
题目相当于转化为选择尽量少的分块,使得每个交点都被覆盖。如果把分块变成左右两端的点,交点变为它们之间的边,则原题目化为最小点覆盖。为什么可以转化?我们发现两个块要么有交点,要么没交点,并且只有横向块与纵向块相交,这完全符合二分图性质。
####BSOJ1775 xinyue 的约会
同上,但需要考虑有些边不需要添加。
####BSOJ2569 网络流 24 题 - 3 最小路径覆盖
把每个点拆成入点和出点,这样一个匹配就是一个边。在匹配中,每一个点的前驱和后继是唯一的,而只有起点不存在前驱,终点不存在后继。有多少个点没有前驱或后继,就有多少条路径。因此对于一个匹配,其路径数 = 点数 - 匹配数。
因此,最少路径 = 点数 - 最大匹配。
有关路径的问题可以将其拆成二分图,再观察路径的性质。
### 最小割
最小割的题目算是比较有价值,也是比较难转换的模型题目。
####POJ2125 Destroying the Graph
每条边可以被入点破坏也可以被出点破坏。因此构造二分图求最小割。
####POJ3469 Dual Core CPU
考虑没有额外代价的情况,则一个任务只能在两个 CPU 的其中一台运行。这个就是最小割模型,$S
考虑加上代价。我们希望当 $ a
往往要从定义出发:割边是连接两个属于不同集合的点的边集。下面的题目也显示出这个特点。
####SPOJ839 Optimal Marks
我们发现因为存在位运算,所有边权的总和最小等价于边权的每一位总和最小。因此单独考虑每一位,且每一位都只有
因此最小割模型显然。把两个集合当成选择的值,向每个点连接容量为
我们得到一个直观的感受:如果一条边不想成为割边,只需要把容量设为
####ZJU2676 Network Wars
见论文。此处重点讨论细节。
对给定网络,我们需要选出一个最小割集。由于分数规划使得边权可能为负,而负边权相当于反边,是不会被计算在最小割的容量的,因此需要手动叠加,而只对边权
####BSOJ2550 网络流 24 题 - 9 方格取数问题
对棋盘黑白染色后发现相邻的不同颜色点之间只能选择其中一个。因此把有冲突的点连边,求最大独立集(权为
####CQOI2017 老 C 的方块
题目描述很复杂,大致就是在一个特殊的网格上不能有特定图形出现,而去除一个网格需要一定费用。
然后我们观察四个图,发现特殊边两侧刚好连接两个格子。“某些状态不能共存,而去掉某个状态需要一定代价” 的想法让我们想到最小割(虽然数据范围上不是这样的)。因此有这些形状的格子要连接起来,并且至少有一个连接源点或汇点。经过一番构图,我们构造出下面这种网络:
每个交点是原图中的一个方块,双线箭头代表图中的特殊边。我们在这张网络图上能发现原图中的四种方块都对应一条从
明显处于
虽然本题点的规模达到了
是道建图好题。我们可以得到一个直观感受:最小割可以解决不共存的最小代价问题。这跟上面利用割的定义最小化分点代价不同,其出发点是源汇点的联通性。
### 最大权闭合图
####BSOJ2543 网络流 24 题 - 2 太空飞行计划
很明显的最大权闭合图模型,直接转化。
####NOI2006 最大获利
见论文。选定一个边同时要选定两个点,转化模型。
####TJOI2015 线性代数
转化题目后发现相当于有许多物品,要得到物品 $ i
有个神奇的做法是暴力寻找不要什么物品,时间复杂度
### 费用流
####BSOJ4914 疯狂的方格取数
拆点。由于网络流与边有关,因此和点有关的题目往往需要把点拆掉来建立边。
####ZJOI2010 网络扩容
第一个最大流很简单。
第二个我一开始估计是在残余网络上操作,然后跑个 DP 计算每条路径扩展 k 所需要的费用,再统计和即可。不过这不好实现还容易 TLE。发现所需费用是费用流的表达式,但是如果直接跑费用流,我们希望有容量的边不计算权值,没流量的边计算权值,怎么办?
残余网络中,原图都加一条边权为
这个思路挺巧妙的,虽然我觉得对
####SCOI2007 修车
本质上是一个打水问题,不过在不同的维修队列里花费时间也不一样。
费用流模型不难想到,可是具有后效性。然而我们发现把每个维修人员的
【未完成】
####NOI2008 志愿者招募
题目太神,不会做。但是还是放上 BYV 的题解。
具体的思路是把不等式添加变量修改为等式,这样容易思考。其次发现每个人都从某段时间开始,某段时间结束,可以考虑到差分。两者结合就得到了新的等式,并且由于差分的特性,每个有关变量都刚好出现两次且符号相反。
啧啧称奇。(虽然我不知道为什么推出来之后,需要求最大流。)
## 总结
网络流通常用来求一类有限制(选择次数、不可同选)的题目。建模相比起算法往往更重要,因此如何构造网络是网络流题目的一个重点。
- 需要掌握图的点与边集关系,尤其是二分图
- 最大匹配数
最小边覆盖数 顶点数(条件:联通图) - 最大独立集
最小点覆盖数 顶点数 - König 定理:最大匹配数
最小点覆盖(条件:二分图) - 最大流
最小割 - 最小割
最小点权覆盖集(条件:二分图) - 最小点权覆盖集数
最大点权独立集数 顶点数(条件:二分图)
- 最大匹配数
- 网络流的建模入手点
- 有关选择的依赖关系的问题,可以考虑最大权闭合图
- 有关路径的问题可以按照出边入边将其拆成二分图,再观察路径的性质
- 有关等式或不等式,考虑流量平衡(如上下界网络流、志愿者招募)
- 有关不共存的最小代价,考虑最小割使源汇不联通的性质,在不共存状态间连边,再与源汇连边求最小割