这东西强,好用,就是难(其实是本人太菜了)。
简介
当一类问题被转化成费用流时,一般来讲时间复杂度的上限是 $O(n^2m)$ 只要出题人想卡,分分钟卡掉(前提是出题人能写出更优的算法,这种都不是人),在这类分支中就有一类优化:模拟费用流。
过于抽象,从模板题讲起走。
例题:
P5470 [NOI2019] 序列
不难想到这是费用流,但观察数据范围发现貌似并不可过。
由此建图可以跑满暴力分,高贵的 $dinic$ 连暴力分都没有跑满,在 $48$ 分在折戟沉沙。
1 |
|
观察建图,不难发现有效流量都集中在左右两边,可以使用带悔贪心的思想找增广路。
可以发现每一条增广路的选择只可能有以下几种情况:
所以一共5种更新可能:
选择$a_x+b_x$中最大的。
选择$a_i + b_i$中最大的。
选择$a$和$b$中最大的($k > l$)。
选择$a$中最大的和$b_x$中最大的。
选择$a_x$中最大的和$b$中最大的。
其中$a_x$表示取了$b_x$但没有取$a_x$的$a_x$值($b_x$同理)。
由上,维护4个堆即可。
- 1:可取的$a$中的最大值。
- 2:可取的$b$中的最大值。
- 3:可取的$a_x$中的最大值。
- 4:可取的$b_x$中的最大值。
每次更新答案即可:
- $1 + 2$($k > l, k-(id_{a_{front}} != id_{b_{front}})$)
- $2 + 3$($l > 0$)
- $1 + 4$($l > 0$)
- $3 + 4$($k ++$)
code
1 |
|
P6122 [NEERC2016]Mole Tunnels
费用流建图不难看出,$10^{5}$ 的数据范围是个人都不会写网络流。
再次分析费用流建图,将树的形态画出来的时候,手玩几组样例就可以发现,每个点可拓展的点十分的少(且已经给定),此时我们对于每一个新增只需跑一次树形dp
即可,此时的时间复杂度已经降为$O(n^2)$了。
再次回顾我们树形dp
干了啥,找离我们目前点的最近点,而我们的树是一颗完全二叉树,考虑动态维护子树中的有食物的点到根节点的最小距离,和这个点的编号,用flow
数组表示我们选择从儿子流向父亲流了多少(从上往下,$flow>0$此边权值为-1
,否则为1
,反之同理)。所以每一次操作,我们顶多沿着链向上跳,一直跳到1
号节点,就可以查询到离这个点最近的有食物的点,之后,对于修改我们顶多会修改两条链上的信息(其他链走都没走),所以时间复杂度降为鼹鼠数$\times$链长度,为$O(m \log n)$,可以通过。
1 |
|