ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】模拟费用流的一些经典题目

2021-09-22 12:36:57  阅读:179  来源: 互联网

标签:第二类 题目 增广 题解 附加 匹配 边冲 模拟 rightarrow


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有