网络流问题本质上是线性规划问题的应用之一,线性规划问题的标准形式是给出一组等式约束和不等式约束,要求最优化一个线性函数。
在流问题中,变量以流量的形式出现在问题中,我们给出一个流网络(以有向图的形式)来解决有关流的问题。
流是整个网络流问题的核心所在,它实际上是定义在流网络上的一个线性函数,在流网络中,每条边都有一个流量 f(u,v) ,流 f=∑v∈Vf(S,v)
流量 f(u,v) 是流问题中的变量,它有两个约束,一个是不等式,一个是等式
(1)容量限制: f(u,v)≤c(u,v)
(2)流量平衡:对于一个 u , ∑v∈Vf(u,v)=0
许多时候我们要求的答案满足二分性,通过网络流算法验证解,二分答案是建模前常用的手段,有的时候二分答案的复杂度可能不如直接一个一个答案枚举来的优,这时候我们不如选择枚举答案
这是解决平面图上问题的最常见技巧,给定一个平面图,我们将原图中的面抽象成点,原来分割两个面的边就在对应的两个点之间连线,构造出原图的对偶图。
网络流的模型总体上分为三种:最大流,最小割和费用流
(尽管总是利用最大流和最大流—最小割定理来解决最小割问题,但两者在建模时的思考方向完全是不一样的)
流量平衡思想
大多数最大流模型都是基于这一思想,题目中有明显的等量/不等关系和变量(01变量非常常见),要求最优化一个函数(可以注意到这其实是线性规划问题)我们可以考虑抽取题目中的约束条件(等式/不等式)进行观察。
<1>要注意每条边都同时作为一个点的出边和一个点的入边,因此,每个变量必然同时关联两个等量关系,且分别出现在这两个等量关系的等号的左边和右边(或者是以一对相反数形式出现);
<2>如果点内部有限制(比如某个点自身的权值不能超过X等等),那么该点内部也“暗含”一个变量,此时就需要拆点(不一定拆成两个点,可能拆成更多的点),然后在拆出的点当中再连边,附加一些限制,然后再考虑流量平衡;
增广路思想
有时候原题的方案的得出可以很明显地分为一些阶段,每一阶段都会对一些变量(这些变量可能是实的也可能是虚设的)产生同样的效果值累加,而这些变量恰好有各自的限制,且互不关联。这刚好相当于网络中的一条从源点到汇点的一条增广路,对路上所有边的流量都会增加,且流量有各自限制(容量),且互不关联。
用增广路思想能够解释的模型往往是一个很明显的“物质路径”模型,某一种物质(可以是实的也可以是虚的)从源点往汇点“走”,边上的流量代表物质经过的量。
BZOJ 1458 士兵占领
大意:给定一个 m∗n 的棋盘,其中 k 个点有障碍,要求放置最少的士兵,使第 i 行有至少 L[i] 个,第 j 列有至少 C[j] 个
解:棋盘行列相关是典型的流量平衡的应用,显然题目中视格子 (i,j) 为 0/1 变量,每行每列都各有一个不等式,题目要求的是 0/1 变量的总和最小,将行列看作二分图,那么就转化为了下界最小可行流了
BZOJ 1305 CQOI dance跳舞
大意:给定 n 个男生和 n 个女生,一些互相喜欢而一些不,举行几次舞会,每次舞会要配成 n 对,不能有相同的组合出现,每个人只能与不喜欢的人跳 k 次舞,求最多举行几次舞会
解:假如已经知道了举行的舞会次数,对于每一个男生/女生就有两个约束,一个是配对过多少人,一个是配对过的不喜欢的人小于等于 k ,我们对于每个点首先源向它连舞会次数容量的边,然后设置若干条容量为1的边连向喜欢的女生,再连向一个虚结点容量为 k (这里描述了第一个约束),虚结点向不喜欢的女生连容量为1的边(这里描述了第二个约束),然后如果该图最大流能流满,说明当前舞会次数下存在可行方案,我们发现舞会次数满足二分性,于是二分答案。
经典问题:二分图最大匹配
BZOJ 1433 ZJOI2009 假期的宿舍 最大流
大意:给定一些人,有些人是在校学生,有些去学校探访,在校学生有些回家,一个人只能睡认识的人的床,求能不能睡下
解:在许多问题中我们需要刻画两个集合之间一一对应的关系,这就是二分图匹配。(集合中任意两个元素的配对是一般图匹配,不在讨论范围内)。
二分图最大匹配有匈牙利算法这样的经典做法,但网络流同样能解决这个问题,对于两个点集中的每个点,都有一个约束条件是邻边被选次数小于等于1,我们直接最大流解决。
BZOJ 3993 Sdoi2015 星际战争
大意:有 n 个机器人和 m 个激光武器,每个武器有一个威力和能打的集合,同一时刻只能打一个机器人,问最少多久可以全灭
解:假如我们知道当前所有武器已经攻击了 t 的时间,那么对于每个武器我们都知道它的总输出是多少,对于每个武器和机器人我们都可以列出一个等式,二分图构图,二分这个时间 t 即可
经典问题:DAG最小链覆盖(可重复/不可重复)
大意:对于一条链来说,除了首尾,中间点都要满足入度=出度,且入度<=1,出度小于<=1,对于一个点,出度入度各有一个方程,拆点拆成二分图,由于点有要求至少经过一次,点内部有流量下界,然后就转化为下界最小可行流了
经典问题:混合图欧拉回路
BZOJ 2095 Poi2010 Bridges
解:有向图欧拉回路存在的充要条件是每个点入度=出度。
随意将原图中的无向边定向,我们可以算出当前每个点的入度与出度,对于一个入度>出度的点来说,它需要将指向它的(入度-出度)/2条边反向,对于一个出度大于入度的点来说,它需要将它指向的(出度-入度)/2条边反向,将所有边是否被反向视作0/1变量,每个点就可以得到一个等式,因此我们将入度>出度与出度>入度分为两个点集,一边连向源,一边连向汇,其他边按原图连边,最大流判断能否流满即可。
BZOJ 1930 Shoi2003 pacman 吃豆豆
大意:找两个不相交的二维上升点列使得两个人一共取到的点价值最大
解:假如有相交,交换两个人的终点就不相交了,所以不用管相交,然后就变成了多阶段的问题,拆点,设上界,构造源汇,一条增广路对应一种方案。
BZOJ 2055 80人环游世界
大意:给定 n 个点,每个点有固定的经过次数, m 个人从任意节点出发任意节点结束,只能向右走,要求总边权和最小
解:拆点设上下界,源点到汇点任意一条增广路对应于一个人的路径。
BZOJ 1449 JSOI2009 球队收益
大意:给定 n 支球队,第 i 支球队已经赢了 wini 场,输了 losei 场,接下来还有 m 场比赛,每个球队最终的收益为 Ci∗x2i+Di∗y2i ,其中xi为最终的胜场,yi为最终的负场
解:发现费用是流量的下凸函数,差分即可。
BZOJ 1283 序列
大意:给出一个长度为 N 的正整数序列 ci ,求一个子序列,使得原序列中任意长度为 M 的子串中被选出的元素不超过 K(K,M<=100) 个,并且选出的元素之和最大。
解:我们考虑约束条件,是若干个不等式
设 a[i] 为第i个数是否选, v[i] 为第i个数的值
对于第 i 个不等式,添加辅助变量 y[i] ,将不等式变为等式
a[1]+a[2]+…+a[n]+y[1]=k
a[2]+a[3]+…+a[n+1]+y[2]=k
…
a[2n+1]+a[2n+2]+…+a[3n]+y[2n+1]=k
ans=max { ∑a[i]∗v[i] }
将相邻两式相减
得
a[1]+a[2]+…+a[n]+y[1]=k
y[1]+a[1]=a[n+1]+y[2]
y[2]+a[2]=a[n+2]+y[3]
…
y[n+1]+a[n+1]=a[2n+1]+y[n+1]
…
y[2n]+a[2n]=a[3n]+y[2n+1]
a[2n+1]+a[2n+2]+…+a[3n]+y[2n+1]=k
发现这里面一个变量关联两个等式,就可以用费用流求该线性规划模型的最值了
最小割是选择流网络的某些边割开使得源汇不连通的最小代价,也就是说对于流网络中的每个点,最小割实际上做了最优代价的 ST 集合划分。
一般我们默认S集为存在/选择集合,T集为不存在/不选择集合。
曾经看到过一篇博客说最小割的线性规划模型是这样的
min{ ∑ max{ (xi−xj,0)∗Wi }
应该说具有一定的参考价值。
通常在最小割问题中我们都能看到以下几个元素
点权:可能是收益也可能是代价
一般来说题目都会要求我们最大化收益,这时候我们可以设想我们拿到了所有的收益,将问题转化为最小化代价,将收益点与S连,代价点与T连,与S割开表示放弃收益,与T割开表示付出代价。
依赖关系:例如i的存在要求某个集合 prei 都存在
假如 i 的存在依赖于 j ,也就是说不允许存在 i 与S联通但 j 与T连通的情况,我们利用割的方向性,构建一条 i−>j 为 INF 的边,那么这样一旦出现 i 与S联通但 j 与T连通的情况,这条边会造成S->T的一个通路,这时候必须选择放弃 i 或选择 j
附加权:对全集 U 的某个子集 u ,它们互相之间存在/或不存在的关系会带来收益/代价
(1)都在S集的额外收益(一般情况的代价不会做)
新建一个点表示 u ,从源向 u 连边,容量为额外收益,从新点向 u 中所有点连边,容量为INF,不允许割开,这样一旦这个集合里有一个与T相连,这条额外收益边就必须被放弃,否则就必须把集合里所有点与T割开。
都在T集的额外收益(一般情况的代价不会做)
新建一个点表示 u ,从 u 向汇连边,容量为额外收益, u 中所有点向新点连边,容量为INF,不允许割开,正确性同上
(2)对于一个二元组, i 在S(T)同时 j 也在S(T)的代价(且图是二分图)
由于是二分图,我们可以将某一个点集连向S和T的容量交换,再在 i和j 之间连双向边即可
(3)对于一个二元组, i 在S j 在T的代价
i 向 j 连一条边,容量为代价,正确性同上。
(4)对于一个二元组, i 在S j 在T的收益
方法同(2),正确性显然
BZOJ 2400 Optimal Marks
大意:给定一个无向图,一些点有权值,其它点的权值可以自己指定,要求指定这些点的权值,使每条边两边的点权异或值之和最小
解:异或值位与位独立,一位一位考虑,发现是01集合划分,一条边两端的点如果在不同集合种会有代价,利用(3)的建图即可
经典问题:最大权闭合子图
BZOJ 1565 NOI2009 植物大战僵尸
大意:给定一个 m∗n 的草坪,每块草坪上的植物有两个属性:
1.啃掉这个植物,获得收益 x (可正可负)
2.保护( r,c )点的植物不被啃掉
任何一个点的植物存活时,它左侧的所有植物都无法被攻击
求最大收益
解:最大权闭合子图,是在一个描述依赖关系的图中最优化选取点集得到最大收益
对于依赖关系,我们可以用之前所说的方式连边。
在此题中,依赖关系可能出现环,因此需要拓扑排序去环
BZOJ 3894 文理分科
大意: 给定一个 m∗n 的矩阵,每个格子的人可以学文或者学理,学文和学理各有一个满意度,如果以某人为中心的十字内所有人都学文或者学理还会得到一个额外满意度,求最大满意度之和
解:属于(1)
BZOJ 2965 保护古迹
大意:给定一个平面图以及一些点,求将1个、2个、3个……点围起来所需要的最小代价
解:平面图转对偶图,枚举围住那些点,找到它们在平面图中所在的面,转化为对偶图上的割
上面几个只是常见的,还有比较精妙的
BZOJ 3218 a + b Problem
解:要求在某个区间内不管有多少个白的只要有就只算一次,因此我们再建一个虚点
然后可持久化线段树优化构图
太神妙了不能多说
我们需要想办法转化为有源汇,考虑流量都为 g[,] 且容量为 C[,]−B[,] 的网络。
为了不忽略 B[,] 这一条件,我们把 g[,] 强制满足下界 B[,] ,但是这时候整个流网络未必满足流量平衡
我们采取这样的方法来解决流量平衡:
添加附加源汇 S,T ,对于某点 u , 设 in(u)=∑(B[i,u])−∑(B[u,j])
若 in(u)<0 , u−>T 连容量为 −in(u) 的边
若 in(u)>0 , S−>u 连容量为 in(u) 的边
然后再 对于任意边 (u,v) 连一条 C[u,v]−B[u,v] 的边.
这样 只需对新的网络求一遍最大流即可. 若出附加源点的边都满流即是存在可行流,反之不然.
从汇点到源点连一条上限为 INF ,下限为 0 的边. 按照无源汇的上下界可行流一样做即可
从汇点 T 到源点 S 连一条上限为 INF ,下限为 0 的边,变成无源汇的网络. 照求无源汇可行流的方法,建附加源点 S′ 与汇点 T′ ,求一遍 S′−>T‘ 的最大流. 再把从汇点 T 到源点 S 的这条边拆掉 . 求一次从 S到T 的最大流即可. (关于 S′,T′ 的边可以不拆)
照求无源汇可行流的方法,建附加源点 S′与汇点T′ ,求一遍 S′−>T‘ 的最大流. 但是注意这一遍不加汇点到源点的这条边. 求完后,再加上那条汇点到源点上限 INF 的边. 因为这条边下限为 0 ,所以 S′,T′ 无影响. 再直接求一遍 S′−>T′ 的最大流. 若 S′出去的边全满流,T−>S 边上的流量即为答案原图最小流,否则若不全满流即无解.