24冬网络流复习题解

A

是谁瞪了半个小时不会 *2000 呀,是谁呀是谁呀。

感觉这题比部分紫题都难。。。

首先发现选取字符的顺序并不重要,所以 \(t\) 可以看成 \(26\) 个字符要选的个数。
设字符 \(c\) 出现了 \(x\) 次,那么直接向汇点连流量为 \(x\) 费用为 \(0\) 的边。

然后考虑 \(s_i\) 与每个字符的关系。
先不管每个 \(s_i\) 限制的选择次数,所以直接向每个字符 \(c\) 连一条流量为 \(c\)\(s_i\) 中出现次数,费用为 \(i\) 的边。

然后考虑每个字符串选择字符次数的限制。
可以直接从源点向每个字符串连接一个流量为 \(a_i\) 费用为 \(0\) 的边,这样最多有 \(a_i\) 流量流出去,所以最多选 \(a_i\) 个。

然后在这张图上求最小费用最大流。

code

B

首先有一个很自然的想法。
每个点 \(i\) 和源点连流量为 \(a_i\) 的边,和汇点连流量为 \(b_i\) 的边,原图有边的点互相连边,然后跑最大流。

但这样无法保证每个人只移动一次。
所以考虑分层,把点分成两层。
假如有一条边 \((x,y)\),就用第一层的 \(x\) 向第二层的 \(y\) 连边,然后第二层的点和汇点连边。

输出方案就看原图中有的点互相连的边的反边的容量即可。

code

C

直接二分 \(d\),然后每条边除以 \(d\) 向下取整,然后就是网络流板子了。

然后本题十分卡精度,所以要开 long double,实测精度二分到 \(10^{-11}\) 可以过。

code

D

费用流好题。

考虑把这个 \(k\) 看成一个费用的限制,所以每个管道变宽 \(1\) 就需要花费 \(1\) 的代。
,所以除了原图的边外再建一条 \(i\)\(j\) 流量为 \(\inf\),费用为 \(1\) 的边(前提是 \(i,j\) 有边)。

然后跑最小费用最大流。
记录当前所经过了的路径的花费,然后每次判断是否超过了 \(k\),超过就取最多能取且没超过的部分,否则直接加上(具体可以看看代码)。

然后证明这样一定不会漏流。
因为跑费用流时是跑的最短路,所以前一条流所需费用一定比当前流小,所以当前流不可选接下来所有的流都不可选。

code

E

由于联通需要的是一颗树,所以实际上只要从 \(n\) 条边里选出 \(n-1\) 条边就可以了,所以直接把工人和边建立二分图,跑最大流即可。

但是有一个问题,由于原图是个奇环树,所以可能会把环上的边全部选上导致环外有点不联通。

所以考虑限制环上边的出现次数,只需要额外建立一个节点,让所有环上边向其连边,然后该点向汇点连一条流量为环大小减一的边即可。

代码还没写。。。

F

直接把科学家和救援仓所在格子建立二分图,然后用广搜判断两个格子是否合法,合法就连边。

code

G

终于到最小割啦!

这种“两权出现取其轻”的模型一看就是最小割。

那么先把边全部选上,所以把边的代价全部加上。

然后考率建图。
点很简单,直接从源点向其连流量为 \(a_i\) 的边就好了。
割掉这条边就相当于选上这个点。

然后考虑建边。
不难想到直接用这条边所依靠的两个点(也就是这条边的两个顶点)向其连边,费用为 \(\inf\)
然后这条边所对应节点向汇点连流量为 \(w_i\) 的边即可。
割掉这条边就相当于不选这条边。

code

H

删除不好做,所以倒过来做增加。

考虑每个值域向所出现过了的社团连边,表示这个值想出现需要依靠这些社团中的一个。

然后社团向汇点连边。
由于每个社团只能选一个人,所以要将社团拆点。

然后维护答案,对于每个值域当作源点跑流,如果有流就让答案增加,第一个跑不出来的值就是答案。

code

I

首先直接二分答案,然后进行 \(check\) ,设当前二分的为 \(x\)

先把 \(l_i\le x\)\(i\) 拿出来。
然后对于每个数,有一个很显然的做法是把合法的数对连边,但无法满足两个数对之间是合法的。

正难则反,考虑把一些数删掉,使得剩下的合法。

所以把和为质数的数相互连边,做成割模型。

可以发现质数大部分都是奇数,所以可以分成奇数偶数两个部分,然后求最小割。

但是 \(2\) 这个数字很特殊。
因为其只能通过 \(1+1\) 平凑,所以无法正常进行。

但是 \(1\) 最多只会选择一个,所以可以找到代价最大的 \(1\),然后将其加入到图中求最小割。

code

J

二叉树每条边只能连两个点,所以先拆点。

由于除根节点外每个点只有一个父亲,所以可以从源点向每个点左点连一个容量为 1,费用为 0 的边。

然后除叶子节点外每个点有两个儿子,所以每个右点向汇点连流量为 2 费用为 0 的边。

然后枚举两个点,如果它们合法就连边,流量为 1,费用为距离。

然后跑最小费用最大流,如果最后最大流为 \(n-1\),就合法。

code

K

看到这个有两种代价的显然最小割。

可以把等级拆点,然后每个低级的点向高级点连边。

割掉这条边的代价就是升到这一级的代价。

然后每个级别的点向需要这个级别的技能连边,跑最小割即可。

code

L

一个非常人类智慧的建图方式。

还是最小割,每个点向其左上角,右上角,最下角,右下角的点连容量为 \(c\) 的边。
表示从这里开始画一个线代价为 \(c\)

每个点向汇点连一条代价为 \(a_{i,j}\) 的边,表示如果该格子没有两个线就不能选。

然后格子上构成了很多斜着的线,从源点向这些线的起始点连边,容量为 \(c\)(详见代码)。

然后跑最小割即可。

code

posted @ 2024-02-28 22:04  caoshurui  阅读(33)  评论(0)    收藏  举报