浅谈上下界网络流
上下界网络流
上下界网络流,即每条边的容量可以有上界和下界。其实普通的网络流容量就是有上界的。所以重点是下界如何处理。基本的处理方法是,通过源点和汇点实现“强制流过”的效果。具体来说,对于原图中的一条边
- 连边
(s,v) ,容量为l 。 - 连边
(u, t) ,容量为l 。 - 连边
(u,v) ,容量为r-l 。
因为直接连到起点、终点的边可以通过求最大流的方式强制满流。于是
下面介绍上下界网络流经常出现的一些形式:
无源汇上下界可行流
没有源点和汇点,每条边给出一个容量上下界,问是否存在合法流(合法流即满足容量限制和流量守恒)。
新建源点
模板:P14578。
有源汇上下界最大流
普通的最大流,容量有上下界的版本。设原图中源点为
从
回到原图。我们现在有一个可行流,于是有一个残量网络,在这个残量网络上再跑
注:从
模板:P14579。
有源汇上下界最小流
同上面的做法,最后在残量网络跑
模板:P14580。
上下界费用流
把所有最大流改为费用流即可。
有负圈的费用流
普通的最小费用最大流,但是存在负费用的环,导致最短路 EK 无法运行。
把负费用看成收益,先强行取走,然后允许反悔。
具体来说,对于一条边
- 将答案加上
cw 。 - 连边
(s,v) ,容量为c ,费用为0 。 - 连边
(u, t) ,容量为c ,费用为0 。 - 连边
(v,u) ,容量为c ,费用为-w 。
这样处理之后,所有费用都是非负数,直接跑最短路 EK 即可。
注:正费用边要保持不变。
注:如果一个带费用的网络一开始没有负圈,那么在最短路 EK 的过程中是不会因为增广引入负圈的。
注:听说有消圈算法:while(找到负圈) 沿着负圈增广,直到没有负圈为止。每次找负圈的复杂度显然是
模板:P7173。
无源汇最小费用流/最小费用循环流
没有源点和汇点。每条边有容量和费用(有负费用),求这张图的最小费用流。
消圈。听说是假做法。
把负费用看成收益,先强行取走,然后允许反悔。
具体来说,新建源点
- 将答案加上
cw 。 - 连边
(s,v) ,容量为c ,费用为0 。 - 连边
(u, t) ,容量为c ,费用为0 。 - 连边
(v,u) ,容量为c ,费用为-w 。
这样处理之后,所有费用都是非负数,直接跑最短路 EK 求最小费用流即可。注意不是最小费用最大流。
P5192 Shoot the Bullet | 东方文花帖
有
第
第
满足以上所有条件的基础上,拍摄尽量多的照片。
做法:每天建一个点,每次拍摄机会建一个点,另外建源点
源点向每天的点连边,容量为
每天的点向当天的拍摄机会连边,容量有上下界
每个拍摄机会向汇点连边,无容量限制。
然后跑有源汇上下界最大流即可。
P4843 清理雪道
给定一个 DAG,选择若干条链,使得每条边都被选中至少一次。问最少选择多少条。
做法:首先有费用流做法。每条边拆边,一条费用为负无穷,容量为
考虑不需要费用流的做法。每条边至少要经过一次,考虑上下界。源点向每个点连边,每个点向汇点连边,容量为无穷。原图的每条边容量有下界
注:可以与 P2764 区分一下。
P4043 支线剧情
给定一个
做法:首先要拆点变为分层图。每个点拆成
源点向
P4194 矩阵
给定一个整数矩阵
做法:最大值最小,考虑二分答案
每行建一个点,每列建一个点。另外建源点
- 源点向每行连边,容量上下界为
[\sum_i A_{i,j}-mid, \sum_i A_{i,j}+mid] 。 - 每行向每列连边,容量上下界为
[L,R] 。 - 每列向汇点连边。容量上下界为
[\sum_j A_{i,j}-mid, \sum_j A_{i,j}+mid] 。
然后跑上下界可行流 check 即可。
CF704D Captain America
在平面直角坐标系上有
此外存在着
你需要在满足这些限制的情况下找到一种花费最少的染色方案,或者报告无解。
输出方案。
做法:这道题数据范围较大,不能用费用流。
因为只有两种颜色,所以花费最少的方案就是让染某种颜色的点尽量少。不妨假设红色比蓝色贵,于是要染尽量少的红色。用流表示红色。
每行建一个点,每列建一个点。另外建源点
- 源点向每行连边,假设该行有
c 个点。如果对该行没有限制,则容量上下界为[0,c] ,否则设限制为d ,则容量上下界为[\lceil (c-d)/2\rceil,\lfloor (c+d)/2\rfloor] 。 - 如果某个位置有点,则所在行向所在列连边。容量上下界为
[0,1] 。 - 每列向汇点连边。假设该列有
c 个点。如果对该列没有限制,则容量上下界为[0,c] ,否则设限制为d ,则容量上下界为[\lceil (c-d)/2\rceil,\lfloor (c+d)/2\rfloor] 。
然后跑有源汇上下界最小流。
CF708D Incorrect Flow
给定一个
题目中输入的流可能不合法,也就是不满足容量限制
你要修改每条边的容量和流量。把每个数值增大
做法:从
对于流量不守恒的点,强行让它守恒。具体来说,对于流入大于流出的点,从该点向
考虑原图中的边。如果已经满足
如果原图中的边满足
对于从
然后跑
注:上面的做法不需要上下界,而且也很自然。我最先想到的是上面的做法。下面介绍题解学来的上下界的做法。
原图中边的部分保持不变。即
- 如果某条边
e=(u,v) 满足f(e)\leq c(e) ,则连三条边(u,v,c(e)-f(e),1) ,(u,v,\infty, 2) ,(v,u,f(e),1) 。 - 如果某条边
e=(u,v) 满足f(e)> c(e) ,则先把答案加上f(e)-c(e) ,然后连三条边(u,v,f(e)-c(e),0) ,(u,v,\infty, 2) ,(v,u,c(e),1) 。
题目中给出的流需要保持。这里用上下界网络流。即对原图中的每条边
然后跑有源汇上下界最小费用可行流。
实际上这两个做法是等价的。