【题解】模拟费用流的一些经典题目
作者:互联网
UOJ 455. 雪灾与外卖
考虑到球 \(a\),匹配前面的一个洞后应该考虑:
- 后面有一个球来抢洞:该球失配,非法。
- 后面有一个洞来抢球:令当前匹配费用为 \(x_a+t\),则相当于让后面的洞匹配了一个权值为 \(-2x_a-t\) 的球。
考虑到洞 \(b\),匹配前面的一个球后应该考虑:
- 后面有一个球来抢洞:令当前匹配费用为 \(x_b+w_b+t\),则相当于让后面的球匹配了一个权值为 \(-2x_b-t\) 的洞。
- 后面有一个洞来抢球:令当前匹配费用为 \(x_b+w_b+t\),则相当于让后面的洞匹配了一个权值为 \(-x_b-w_b\) 的球。
注意到因为一个洞会出现很多次,所以可以多次考虑匹配,当匹配不优的时候就把剩下的洞一股脑的丢进堆里即可。
代码:提交记录 #507879 - Universal Online Judge (uoj.ac)
ICPC World Finals 2018 征服世界
在 lca 统计贡献,如果堆顶可以使得答案更小那么更新(注意到因为要求所有球必须进洞,所以最开始给每个球一个极小附加权值保证每个球都会被匹配),同时添加反悔。
注意到因为两个匹配点不可能同时反悔(不会使得答案变优),所以总共需要处理的球和洞的级别是军队总数的,时间复杂度 \(O(S\log S)\) 。
代码:提交记录 #1254764 - LibreOJ (loj.ac)
NOI2019 序列
依次加入 \(a_i\),考虑增广路怎么走:
- \(S\rightarrow a_i\) 然后 \(a_i\rightarrow b_i\) 最后 \(b_i\rightarrow T\) 。 (走第一类匹配边)
- \(S\rightarrow a_i\),然后 \(a_i\) 走附加边去到某个 \(b\) 后去 \(T\) 。(走第二类匹配边)
- \(S\rightarrow a_i\) 然后 \(a_i\rightarrow b_i\),接着冲掉之前和 \(b_i\) 匹配的点,走附加点回到 \(a_j\),对应点 \(a_j\) 走对应的 \(b_j\) 到 \(T\) 。(走第一类匹配边冲第二类匹配边变为第一类匹配边)
- \(S\rightarrow a_i\) 然后 \(a_i\rightarrow b_i\),接着冲掉之前和 \(b_i\) 匹配的点,走到附加点寻找新的匹配 \(b_k\) 走到 \(T\) 。(走第一类匹配边冲第二类匹配边变为第二类匹配边)
- \(S\rightarrow a_i\),然后 \(a_i\) 走附加边去对面选点,冲掉之前走附加边的某个 \(a_j\),让 \(a_j\) 走 \(b_j\) 到 \(T\) 。(走第二类匹配边冲第二类匹配边变为第一类匹配便)
一共五种简单的增广路(注意到不会有 "走第二类匹配边冲第二类匹配边变为第二类匹配边" 的情况,这种情况和 "走第二类匹配边" 没有区别,因为不关心谁匹配了谁)。
注意到正常描述增广路的方式应该是 "在左右点乱跳,然后最后跳到 \(T\) 表示找到一对新的匹配",看样子不能简单归为上面五种。
但其实对于这样的增广路,可以先找到重复点直接 匹配,容易发现这样子肯定不会变劣,所以最开始就不会出现左右部点重复的情况。接着考虑剩下的东西,注意到模拟费用流时,存下来的反悔方案都不用具体地表示出增广路:这意味着,我们知道左右部匹配了多少点,但是不用关心具体怎么匹配的(事实上模拟费用流都是这样的)。所以我们认为新增节点的时候,只需要讨论上述五种简单的增广路。
讨论一下这五类增广路碰到的点的状态:
- \(a_i\) 未匹配,\(b_i\) 未匹配:\(a_i+b_i\) 最大。
- \(a_i\) 未匹配,\(b_i\) 不管;\(a_j\) 不管,\(b_j\) 未匹配:\(a_i+b_j\) 最大。
- \(a_i\) 未匹配,\(b_i\) 已匹配;\(a_j\) 已匹配,\(b_j\) 未匹配:\(a_i+b_j\) 最大。
- \(a_i\) 未匹配,\(b_i\) 已匹配;\(a_j\) 已匹配,\(b_j\) 不管;\(a_k\) 不管,\(b_k\) 未匹配:\(a_i+b_k\) 最大。
- \(a_i\) 已匹配,\(b_i\) 未匹配;\(a_j\) 不管,\(b_j\) 已匹配;\(a_k\) 未匹配,\(b_k\) 不管:\(a_k+b_i\) 最大。
可以发现后两条中间的 \(a_j\) 其实不需要讨论,此时只需要维护:
- \(a_i\) 未匹配,\(b_i\) 未匹配:\(a_i+b_i\) 最大。
- \(a_i\) 未匹配,\(b_i\) 已匹配:\(a_i\) 最大。
- \(a_i\) 已匹配,\(b_i\) 未匹配:\(b_i\) 最大。
- \(a_i\) 未匹配,\(b_i\) 不管:\(a_i\) 最大。
- \(a_i\) 不管,\(b_i\) 未匹配:\(b_i\) 最大。
将所有的 \(i\) 分为了五类,用五个堆维护,然后模拟五种增广路带来的影响即可。
代码:提交记录 #1256954 - LibreOJ (loj.ac)
考虑增广路好像还要有顺序的,如果顺序错了就是过不去?我是真的不懂。
标签:第二类,题目,增广,题解,附加,匹配,边冲,模拟,rightarrow 来源: https://www.cnblogs.com/qiulyqwq/p/15319395.html