线性规划与网络流24题

Published on 2016-03-23

终于做完了,我是在 COGS 上面做的,首先来几点吐槽:

  • COGS 居然只能提交文件,对于我这种目录深的,表示很不习惯。
  • COGS 输入输出用文件,这个不评论了,各有喜好。
  • COGS 对网络流24题收录不全,仅仅只有 21 道题
  • 网络流24题中,有些题描述很不严谨,甚至连范围都没有给。
  • 网络流24题中,有几题不能做,有几题数据有问题,还有很多题几乎就是水题,还有几题就不是网路流。

但不可否认,还是有几题是比较好的,建议有选择的做,下面一一点评(借用一下 BYvoid 的表)

问题编号 问题名称 问题模型 转化模型 点评
1 飞行员配对方案问题 二分图最大匹配 网络最大流 模板题
2 太空飞行计划问题 最大权闭合图 网络最小割 最小割模型不错
3 最小路径覆盖问题 有向无环图最小路径覆盖 网络最大流 拆出入点模型不错
4 魔术球问题 有向无环图最小路径覆盖 网络最大流 转化判定性问题,多次增广,不错
5 圆桌问题 二分图多重匹配 网络最大流 模板题
6 最长递增子序列问题 最多不相交路径 网络最大流 数据有问题,但思维不错
7 试题库问题 二分图多重匹配 网络最大流 模板题
8 机器人路径规划问题 (未解决) 最小费用最大流
9 方格取数问题 二分图点权最大独立集 网络最小割 规约到二分图最小点权点覆盖,不错
10 餐巾计划问题 线性规划网络优化 最小费用最大流 重复利用流,很不错
11 航空路线问题 最长不相交路径 最小费用最大流 费用流建图,一般
12 软件补丁问题 最小转移代价 最短路径 位运算优化,并不是网络流
13 星际转移问题 网络判定 网络最大流 时间模型,不错
14 孤岛营救问题 分层图最短路径 最短路径
15 汽车加油行驶问题 分层图最短路径 最短路径
16 数字梯形问题 最大权不相交路径 最小费用最大流 建图,对边、点的限制,一般
17 运输问题 网络费用流量 最小费用最大流 模板题
18 分配问题 二分图最佳匹配 最小费用最大流 模板题
19 负载平衡问题 最小代价供求 最小费用最大流 建图,一般
20 深海机器人问题 线性规划网络优化 最小费用最大流 费用流建图,一般
21 最长k可重区间集问题 最大权不相交路径 最小费用最大流 K流问题,经典
22 最长k可重线段集问题 最大权不相交路径 最小费用最大流
23 火星探险问题 线性规划网络优化 最小费用最大流
24 骑士共存问题 二分图最大独立集 网络最小割 与 9 类似,但有个思维转化

只对我认为比较好的题来题解:

最小路径覆盖问题 - 3

构造二分图,把原图每个顶点 ii 拆分成二分图 XXYY 集合中的两个顶点 XiX_iYiY_i。对于原图中存在的每条边 (i,j)(i,j),在二分图中连接边 (Xi,Yj)(X_i,Y_j)。 新建源汇 s,ts, tss 向每个 XiX_i 连边,YiY_itt 连边。然后把二分图最大匹配模型转化为网络流模型,求网络最大流。
最小路径覆盖的条数,就是原图顶点数,减去二分图最大匹配数。沿着匹配边查找,就是一个路径上的点,输出所有路径即可。
我们认为 XX 集合代表每一个点的出点,YY 集合代表每一个点的出点,由于要求的是路径的集合,我们先研究单条路径。显然,每个点属于且仅属于一条路径,那么意味着出来路径的起点和终点,每个点都有唯一的前驱和后继,那么从 XiX_i 出发的边指向后继,从指向 YiY_iii 的前驱,所以原先 (u,v)(u, v) 的边,就变为了 (Xu,Yv)(X_u, Y_v)。而起点的前驱是 ss,终点的后继是 tt,由于每个点都有可能是路径端点,所以从 ss 向每个 XiX_i 连边,YiY_itt 连边。
注意到每个条路径只有一个终点,而除去终点外的所有点 XiX_i 均被匹配,所以有多少个未被匹配的 XiX_i,就有多少条路径。

总结:对于路径问题,通常将点拆为入点和出点,利用二分图的性质。

魔术球问题 - 4

转换思路,不好求有 nn 个柱子时可放的球数量,我们求可放 nn 个球时的最小柱子数量,注意到同一个柱子上球的标号递增,所以可以转化为最小路径覆盖问题。
枚举答案 TT,在图中建立节点 1,2,...,T1,2,...,T。如果对于 i<ji<j i+ji+j 为一个完全平方数,连接一条有向边 (i,j)(i,j)。该图是有向无环图,求最小路径覆盖。如果刚好满足最小路径覆盖数等于 nn,那么 TT 是一个可行解,在所有可行解中找到最大的 TT,即为最优解。可以顺序枚举 TT 的值,当最小路径覆盖数刚好大于 nn 时终止,T1T-1就是最优解。
最小路径覆盖数随球的数量递增不递减,满足单调性,所以可以顺序枚举答案(或二分答案),对于特定的答案求出最小路径覆盖数,一个可行解就是最小路径覆盖数等于 nn 的答案,求出最大的可行解就是最优解。本问题更适合枚举答案而不是二分答案,因为如果顺序枚举答案,每次只需要在残量网络上增加新的节点和边,再增广一次即可。如果二分答案,就需要每次重新建图,大大增加了时间复杂度。

总结:有些时候要转换思路,寻求问题容易求解的形式,转化为判定性问题,而判定问题有时更适合枚举答案,在原图上加点。

最长递增子序列问题 - 6

O(n2)O(n^2) 的动态规划求出 f[i]f[i],表示以第 ii 为结尾的最长上升序列的长度,maxf[i]\max f[i] 就是最长上升序列长度,记 K=maxf[i]K = \max f[i]
第二问,问的是同时取出,每个数只能用一次!由于最长上升子序列有阶段性的特征,即 f[i]f[i] 的值为阶段,所以流量的流动,就像阶段的转移,考虑建图:

  1. 把序列第 ii 位拆成两个点 ia,ibi_a, i_b,从 iai_aibi_b 连接一条容量为 1 的有向边。
  2. 建立附加源 ss 和汇 tt,如果序列第 ii 位有 f[i]=1f[i]=1,从 ssiai_a 连接一条容量为 1 的有向边。
  3. 如果 f[i]=Kf[i]=K,从 ibi_btt 连接一条容量为 1 的有向边。
  4. 如果 i<ji < jA[i]<A[j]A[i] < A[j]f[j]+1=f[i]f[j]+1=f[i],从 ibi_bjaj_a 连接一条容量为 1 的有向边。

显然,拆点的目的是为了限制每个点只能用一次,对于 f[i]=1f[i] = 1 的点,是阶段的开始,f[i]=Kf[i] = K 的点,是阶段的结束,而第 4 条,即为阶段的转移,一束流量为 1 的流,只有经过 K1K - 1 次转移,才能到达汇点,而每一束到达汇点的流,均一一对应一个 LIS。因此第二问的答案就是本图最大流。
(1a,1b)(1_a, 1_b)(na,nb)(n_a,n_b)(s,1a)(s,1_a), 这三条边以及如果 f[n]=Kf[n] = K 的话,(nb,T)(n_b,T) 的容量修改为无穷大,再求一次网络最大流,就是第三问结果。
当然数据有问题,建图应该是对的。

总结:有的时候流量流动的意义非常重要,它可能代表着阶段的转移,这种阶段图的思想很重要。

方格取数问题 - 9

很妙的建图,将棋盘黑白染色,发现只有不同颜色的格子,才可能冲突。将每个格子看作一个点,如果我们将有冲突的格子之间连边的话,会发现这是一个二分图。

  1. 将黑点放在 XX,白点放在 YY
  2. 增加源 ss 和汇 tt,将每条二分图的边 (u,v)uX(u, v) u \in X 替换为容量为 \infty 的有向边 (u,v)(u , v)
  3. 对于 XX 集中的每个点 uu,从 ss 向其连一条有向边,容量为该点的数值;对于 YY 集中的每个点 uu,从 uutt 其连一条有向边,容量为该点的数值。

不难发现,此图的最小割就是原图的最小点权覆盖集,而二分图最小点权覆盖集的补集就是二分图的最大点权独立集。
有关二分图最大点权独立集问题,更多讨论见《最小割模型在信息学竞赛中的应用》作者胡伯涛。

总结:经典模型的学习是很重要的,要理解,更要会应用!

餐巾计划问题 - 10

一开始自己做的时候,不知道将每一天用完的餐巾这股流弄到那里去好,如果流向汇点,那么就无法送去洗,如果送去洗,又无法保证到汇点满流,于是只好看题解。
这个问题的主要约束条件是每天的餐巾够用,而餐巾的来源可能是最新购买,也可能是前几天送洗,今天刚刚洗好的餐巾。每天用完的餐巾可以选择送到快洗部或慢洗部,或者留到下一天再处理。
在每一天的餐巾需求为 rir_i 的情况下,如果满足,必定余下 rir_i 个餐巾可以任意处置,所以我们新增流而不是将已经用的流流回。
把每天分为二分图两个集合中的顶点 XiX_iYiY_i,建立附加源 sstt

  1. ss 向每个 XiX_i 连一条容量为 rir_i,费用为 0 的有向边。表示每天用完的餐巾
  2. 从每个 YiY_itt 连一条容量为 rir_i,费用为 0 的有向边。表示每天必须满足的需求
  3. ss 向每个 YiY_i 连一条容量为 \infty,费用为 pp 的有向边。表示购买餐巾。
  4. 从每个 XiX_iXi+1(i+1N)X_i+1(i+1\le N) 连一条容量为 \infty,费用为 0 的有向边。表示餐巾,是可以放着不洗存到下一天的。
  5. 从每个 XiX_iYi+m(i+mN)Y_i+m(i+m\le N) 连一条容量为 \infty,费用为 ff 的有向边。表示快洗。
  6. 从每个 XiX_iYi+n(i+nN)Y_i+n(i+n\le N) 连一条容量为 \infty,费用为 ss 的有向边。表示慢洗。

此图最小费用最大流即为答案。

总结:本题反映了分析一类问题的方法,分析问题的约束条件,分析问题的所有可能决策,从而有的放矢的建图。边,有时候意味着一种决策,我们利用网络流,来获得最优决策。新增流的手法也是很重要。

骑士共存问题 - 24

与 9 很类似,黑白染色,显然只有不同颜色的点才有可能冲突,不同的是多了障碍物。
我们屏蔽一切连向障碍物的边,求最大独立集,不难发现障碍物也属于独立集,从独立集中去除障碍物,由于我们建图的攻击关系是完全的(障碍物不攻击别人也不被攻击,其余的马会相互攻击),一定有剩下的部分是原图的最优解。

总结:学会一个模型,还要灵活应对模型的变体。