网络流相关问题选讲

ShanLunjiaJian

今天切什么

不知道。继续看就知道了!那么这一页为什么存在呢?

放了一些比较educational的题,希望可以让大家有事干。技术水平要求不是很高,应该可以随时断线重连吧(

$\infty$表示一个非常大的数。

请提醒我对电子白板截图并塞进这里面。

但是还是忘了这件事!

建图

一些建图问题。

基础建图练习

ctt2017 无限之环

棋盘上每个格子有一个水管,水管有以下这些种。

你每次可以选择一个向任意方向旋转90度,I型水管是不能旋转的,求最小的旋转次数,使得没有一个接头没有和另一个接头对上。

hint

匹配。匹配。

solution

考虑到网络流之后,首先考虑都不转怎么做。黑白染色,让黑格的接头匹配白格的接头即可。

如果可以转。考虑Q型

直接连。考虑L型

相当于横向和纵向是独立的,分别拆点即可。考虑T型

可以解方程解出每个位置的代价。也可以多加几条边。

联合省选2022 学术社区

不会写形式化题意。大家可以,自己看一下!

hint

类似最小边不交路径覆盖来做。

solution

考虑性质C。如果$i$后面接$j$可以让其中一条合法,就给$i$的出点连到$j$的入点,然后跑二分图匹配。

但是有问题,如果跑出了一个环,有一条边就需要出现两次。注意到一个点上的所有环可以合为一个,而每个点都有至少一个学术消息,把环挂到学术消息上就行了,此时它还是可以相当于一个学术消息来用。

对于楼上楼下的二元环,直接把它俩放在一起是不劣的,因为如果有一个最优解中它俩不在一起,改为连着后面挂着的东西接到一起就是不劣的。

为了构造方案,不停从一条还没用的消息出发往两边dfs即可。如果找到了环则挂给环上任何一个点的学术消息,如果找到了链则加入答案。

cf1404 E. Bricks

棋盘,每个格子可能是黑色或白色,你要用若干宽度为$1$的横条或者竖条覆盖所有黑格子,不能交叉,也不能覆盖到白格子,求最少用多少个。$n,m\leq 200$。

hint

匹配。匹配。

考虑每条格子边是不是在一个条的内部。

solution

也就是,一个格子的两条相邻的边不能同时在内部,至少一侧是白格子的边不能在内部。二分图最大独立集即可。

循环流

最小费用循环流。具体地,每个点入流等于出流,每条边流量不超过上限。

hint

如果没有可以增广的负环,则找到了一个最小费用循环流。

考虑先不管入流等于出流,消掉所有负环,然后用有源汇费用流消掉超额流。

solution

先把所有正权边充满,然后进行调整使得入流等于出流。源提供正的超额流,也就是说删掉源之后超额流为负,所以源连到每个超额流为正的点,汇连到每个超额流为负的点,以把超额流抵消成$0$。

可行流

边还有流量下限。

solution

先把所有边充到下限,然后变成有超额流的最小费用循环流问题。一开始有超额流并没有带来什么困难。

noi2008 志愿者招募

序列,给若干个区间,每个有一个费用,你可以支付费用并给区间$+1$,一个区间可以选多次。每个位置有一个$\geq a_i$的限制。求满足所有限制的最小花费。

hint

这是一个经典题。

单源汇流的问题在于,我们不知道这个流量是从哪来的,因此不知道它应该到哪去。

solution

循环流。用一条边表示一个区间,那么它可以在一端提供正的超额流,另一端提供负的超额流。

对于序列的限制,最小费用可行流即可。

arc137 E. Bakery

序列,给若干个区间,每个有一个费用,你可以支付费用并给区间$+1$,一个区间只能选最多一次。每个位置加到$a_i$则不会再增加。最后你会获得序列总和$\times d$的价值,最大化价值减去花费。

hint

这是一个简单题。

solution

循环流。用一条边表示一个区间,相邻两个位置之间连一条容量$a_i$费用$d$和一条容量$\infty$费用$0$的边表示对$a_i$取$\min$。

最小割

以下默认权值都是正的。

hnoi2013 切糕

$n\times m$的棋盘,每个位置填一个$1,...,k$中的数,给出每个位置填每个数的代价。四连通的格子填的数不能相差超过$d$。求最小代价。

solution

二维问题还是比较劲爆。每个格子建一条链,割第$i$条边表示填$i$,容量为$\infty$加上代价。黑白染色,对于相邻两个格子的两个相差$>d$的选择$i < j$,从$i$的下侧连到$j$的上侧,容量为$\infty$。

当然这些边只有相距恰好$d$的是有用的。

也许是不知道哪年ctt 人员雇佣

有$n$个人,每个人选有一个代价$a_i$,每两个人$i,j$(无序)如果都选贡献$2e_{i,j}$,一个选一个不选贡献$-e_{i,j}$,都不选没有贡献,最大化总贡献。

hint

这里是最大化,所以先选所有正权的东西。

solution

先配凑,如果$i$选,花费$a_i$,否则花费$\sum\limits_j e_{i,j}$。如果$i,j$一个选一个不选,额外花费$2e_{i,j}$。直接建即可。

当然有各种别的建图。

thupc22 I. 分组

有$n$对人。每个人可以选择愿意或不愿意合作,各有一个代价,如果一对人都选择愿意,那么这一对可以选择合作或不合作,否则只能选不合作。如果一对中两个人选择不同,会产生一个代价。有若干个跨对的单向关系$i\rightarrow j$,表示 : 如果$i$的对不合作,而$j$选择愿意,会产生一个代价;如果$i$选择不愿意,而$j$的对选择合作,会产生另一个代价。求一个选择最小化代价。

hint

大力放进去所有东西。

solution

每个人建一个点,每个对建一个点,不割哪边表示选哪边,边权比较显然。

特殊图

单位圆图最大团

平面上有一些点,两个点距离$\leq 1$则连边,求最大团。$n\leq 100$。

hint

需要性质。

solution

最大团必然包含在其中最远点对 分别为中心,半径为$1$的圆 的交中。从中间画一条线,其补图是二分图。

ccpc2021 Weihai L. shake hands

序列,一开始是$1,...,n$,有若干次操作,每次交换相邻两个数,并在这两个数之间连边,求最大团。$n\leq 10^5$。

hint

需要性质。

solution

注意到如果$i< j< k$,$i,j$没有换过,$j,k$没有换过,那么$i,k$也没有换过。也就是说$<$并且没有换过是一个偏序关系,那么这是一个可比图。可比图的最大独立集就是最长反链。

至于怎么快速跑最长反链,如果剩下时间再讲。

模拟费用流

在特殊图上更快地求解费用流。

凸性

显然费用流的答案随流量是凸的,因为沿最短路增广,每轮增广后,到每个点的最短路都不会变短。

xx open cup gp of kazan H. Honorable Mention

序列,查询区间选恰好$k$段非空的最大子段和。$n,q\leq 5\times 10^4$。

hint

凸函数处理全家桶。

在序列上建线段树。

solution

状压两侧的情况,线段树每个点闵和一个凸函数。查询的时候我们要合并$\log$个凸函数并求一点的值,可以wqs二分。复杂度$O(n\log^3 n)$,分散层叠一下可以砍一个$\log$。

pre-knowledge

看起来我要说的不少。

模拟

真的去跑这个费用流,但是利用性质可以优化。

相比wqs二分,模拟/直接维护凸函数 可以求出所有流量的答案。

一些简单结论

显然我们只需要找到权值最小的增广路/任意一个负环。

如果一开始没有负环,那么每次找权值最小的增广路也不会产生负环,因为到每个点的最短路不会变短。

简单推论是,如果没有负环,不停找增广路,那么连源/汇的边不会退流,因为退源汇边的流就找到了负环。

存在一个权值最小的增广路/负环经过每个点最多一次,否则它可以拆成一个增广路/负环和一个负环,其中一个权值必然更小。

xx open cup gp of spb F. Festive Baobab

有根树,每条边有一个价值,你要选$k$条边,一条边可以选多次。每个子树还有一个选的个数上限。最大化价值。$n\leq 2\times 10^5,k\leq 10^9$。

hint

这是一个签到题。

solution

可以发现这里压根不会反悔,因为你只能沿着树往下走。

按价值从大到小扫,树剖线段树维护能增广多少。

icpc20 Shenyang L. Forged in the Barrens

序列,对于每个$k$,求把序列划分成$k$段,每段极差之和的最大值。$n\leq 2\times 10^5$。

hint

把极差改成任意两个数的差。

solution

费用流,从钦点的$\min$流到钦点的$\max$,这里需要不交所以拆点限制一下。这就证明了凸性,接下来可以状压两侧的情况分治闵和,或者直接模拟费用流。

具体描述后者。源汇边不会退流,也就是说选了的会一直被选。可能的操作有,把一对从中间炸开变成两对,或者在两对之间再选一对。

线段树维护区间 前面选$\min$,后面选$\max$ 的最大差,或者反过来,然后全局开个堆,每次取出一段之后,把分裂出来的部分再扔回堆里即可。

pa2013 Raper

$n$天,有$k$个物品需要先后经过AB两间工厂加工,每天每间工厂只能加工一个物品,并且每天有一个费用,求最小的总费用。$n\leq 5\times 10^5$。

hint

这是一个强硬题。

solution

可能的增广路有,从左往右或者从右往左。从右往左要求这一段都有向右的流量。

大力线段树。对于从左往右,也就是左边选一个$a$,右边选一个$b$的$\min$,和上个题是差不多的。对于从右往左,直接维护两边有流量的部分。主要问题是打加减法标记的时候怎么做,发现只要$\min>0$那从右往左也是几乎自由的了,而$\min$不可能$<0$,所以维护自由选的最优策略,以及(通过整体减)减到$\min=0$之后的最优策略即可。

洛谷1484 种树

序列,选$k$个数,不能选相邻的两个,求最大和。$n\leq 5\times 10^5$。

hint

最大权独立集。链当然是二分图!

需要一点性质。

solution

这是一个二分图最大权匹配。考虑增广路的形态,必然是把一段选了恰好一边的取反,然后选它的一边。

考虑相邻的三段。

也就是说每选择一段会合并它和两边。链表维护即可。

集训队胡策2022 R1 A. Astral Brith

$01$序列,对每个$k$,求划分成$k$段并重排得到的lis长度最大值。$n\leq 3\times 10^5$。

hint

考虑很多个性质。有没有老哥来猜点性质?

solution

转而考虑不在lis中的数,我们把它们都扔掉,剩下的数会形成若干段,这个段数$-1$几乎就是需要的步数,$-1$是因为有一段可以是前一半0后一半1,几乎是因为还需要考虑整个序列前面全1后面全0的情况,不过我们先不考虑它。

考虑先把相同的一段缩成一个,显然相同的一段要么都扔要么都留。我们在中间扔一个数,会合并两边,于是减少了两段,而扔两边则只减少一段。如果直接贪心选可能会扔相邻的两个,此时减少的段数是错误的,但是显然相邻的两段不会同时被扔,因为只扔一段就可以把另一段并入别的一段。

看起来 不能选相邻的两个,求最大和 这个问题就是 种树。枚举两边扔不扔,我们就知道要选多少个中间的,然后 种树 即可。

加边

有些时候按某种顺序加点/边并考虑新产生的增广路和负环会更简单。

此时 存在一个权值最小的增广路/负环经过每个点最多一次 仍然成立。

cf865 D. Buy Low Sell High

给一支股票接下来$n$天的价格,一开始你持有$0$股,每天你可以买一股,卖一股,什么都不做,你的钱可以变成负数,但是持有的股票数不能是负数,求最大收益。$n\leq 3\times 10^5$。

hint

先建个费用流出来。从左往右加点,大力考虑所有可能的增广路和负环。

solution

加入一天的时候,新增的增广路有,在之前某一天买,在这一天卖;负环有,不再在之前某一天卖,而是在这一天卖。直接维护即可。

uer8 雪灾与外卖

数轴上有若干送餐员和餐馆,坐标序列分别是$x,y$,每个餐馆$i$有$c_i$份价格$w_i$元的菜,送餐员$i$到餐馆$j$取餐需要花费$\vert x_i-y_j\vert$元,求让每个送餐员都取到一道菜的最小花费。$n,m\leq 10^5$。

hint

先建个费用流出来。从左往右加点,大力考虑所有可能的增广路和负环。

需要一些劲爆性质。

solution

原来的版本写挂了。请见 [感性理解 uer8 雪灾与外卖](https://shanlunjiajian.blog.uoj.ac/blog/8238) 。

怪题

cf724 E. Goods transportation

源到每个点连容量为$p_i$的边,每个点到汇连容量为$s_i$的边,还有一个数$c$,对于点$i< j$,$i$到$j$连容量为$c$的边。求最大流。$n\leq 5000$,可以做到$n\leq 10^6$。

hint

转为最小割。

solution

也就是要把点分入$S,T$两个集合,选$S,T$各有代价,并且如果$i< j$,$i,j$不在同一集合,要付出$c$的代价。

已经可以dp,设$dp(i,j)$表示前$i$个,有$j$个在$S$中的最小代价,转移显然。

存在一个离奇贪心。考虑如果没有$i< j$,那么如果选了$k$个$S$,总要付出$k(n-k)$次$c$。所以我们枚举$k$,也就是先全选$S$,然后找到$s-p$前$k$小的改为选$T$。

现在有$i< j$。配凑,让$p_i\leftarrow p_i+(n-i)c$,那么我们恰好会多付出$\binom{k}{2}$次$c$。

Thanks for Listening!

Powered by reveal.js