线性规划与网络流24题解题报告
网络流24题是一套经典的网络流题目, 来自<计算机算法设计与分析, 王晓东>[1].本题解参考了教材的官方答疑[2], 和几位神犇orz的博客[3][4][5].
1. 飞行员配对方案问题
- 最大流, 二分图最大匹配
裸的二分图最大匹配.
2. 太空飞行计划问题
-
最小割
-
有一些实验, 实验需要一些仪器, 购置仪器的费用为\(c_k\), 实验做出来可以获得\(p_k\)美元. 选择购置哪些仪器使得
- 显然这个题目是一个决策每个方案是否选择的问题, 可以转化成最小割模型, 我们由\(s\)向每个仪器连一条容量为\(c_k\)的边, 由实验向汇连一条容量为\(p_k\)的边, 这样,
3. \(\star\)最小路径覆盖问题
-
二分图最大匹配, 网络流
-
给定有向图\(G=(V,E)\), 设\(P\)是\(G\)的一个简单路径(顶点不相交)的集合, 如果\(V\)中的每个点都在\(P\)的一条路径上, 那么称\(P\)是原图的一个路径覆盖. \(G\)的最小路径覆盖是\(G\)的所含路径条数最少的路径覆盖. 求DAG\(G\)的最小路径覆盖.
-
我们考察一个路径覆盖的性质:
- 每个顶点属于且仅属于一个路径.
- 路径上除了终点, 每个点都恰好有且仅有一条边指向路径上另一个点.
可以发现这种性质类似二分图性质, 我们把点拆成两个点, 一个作为起点, 一个作为终点, 那么每一条原图中的边都对应着二分图中的一个匹配, 因为一个点仅能被一条边覆盖, 所以在二分图中每一个合法的匹配都唯一地代表了一种路径覆盖方式. 最开始的时候, 我们可以看作每个点都自身作为一个路径, 这样, 每增加一个二分图匹配, 集合的基数就减少一, 那么我们只要算出二分图的最大匹配, 用点的个数减去它就可以了.
-
这个题目的关键就是发现潜在的二分图性质.
-
注意, 这种建模方式仅限于DAG, 因为如果有环, 那么可能对应了一些环覆盖, 而不是路径覆盖.
4. 魔术球问题
- 最小路径覆盖, 最大流
- 假设有n根柱子, 按照以下规则在这n根柱子中依次放入编号为1,2,3的球,
- 每次只能在某根柱子的最上面放球
- 满足相邻任何一根柱子上相邻两个球的编号之和为完全平方数
- 如果存在\(i < j\)使得\(i+j\)是完全平方数, 连边\(i \rightarrow j\)
- 那么对于有这样\(n\)个顶点的图\(G\), 显然地\(G\)的最小路径覆盖确定了柱子数
- 我们可以二分答案使用上面的方法验证
- 也可以证明, \(n\)个柱子能够放入的最多球数为\(\lfloor \frac {n^2+2n-1}2 \rfloor\).(我不会证)
5. 圆桌问题
-
最大流
-
有\(n\)个来自不同单位的代表, 每个单位的代表数分别为\(r_i\), 会议餐厅共有\(m\)个餐桌, 每个餐桌可以容纳\(c_i\)人, 同时同一个单位的代表不能在同一个餐桌用餐.
-
不难建图:
- \(s \xrightarrow{r_i}\)单位
- 单位\(\xrightarrow{1}\)餐桌
- 餐桌\(\xrightarrow{c_i}t\)
跑一遍最大流即可
6. 最长递增子序列问题
- 最大流
- 给定正整数序列, 求从给定的序列中最多可以取出多少个长度为\(s\)的LIS.
- 和SDOI某年一道题很相似
- 首先如果对于\(i < j, f_i < f_j\)连边\(i \rightarrow j\)
- 然后有两种做法, 一种是拆点放限制, 一种是在边上搞, 其实都无所谓.
7. 试题库问题
- 最大流
- 有\(n\)道试题, 知道他们所属的类型, 求一种算法使得可以出一套有\(m\)个题目的试卷包含\(k_i\)个某种类型的题目.
- 建图:
- s到每种类型, 容量\(k_i\)
- 每个试题到t, 容量1
- 试题到类型连边容量1
8. 机器人路径规划问题
-
未解决
-
机器人在一个树上自由移动, 给定树上两点s和t, 树上有若干可移动的障碍物, 任何时刻两个物品不能在同一个节点上. 移动某个物品(机器人或障碍)的代价是1. 您需要使用最小的代价移动机器人从s到t.
-
本题是一个著名的树形路径上的路径规划问题, 成为了"网络流24题"中唯一没有得到解决的问题. 事实上, 这个问题并不是一个网络流问题, 虽然有一个\(O(n^9)\)的算法, 但是非常缓慢[6], 有兴趣的同学可以参考文献[6].
9. 方格取数问题
-
最大流, 拆点, 二分图最大独立集
-
在一个\(m \times n\)的棋盘中, 每一个方格中有一个正整数, 现要从方格中取数使得取到的任意两个数不相邻, 且取出的数总和最大.
-
一看见棋盘, 不管它问什么, 我们就要先黑白染色
(笑). 这样, 显然格子组成了一个二分图, 然后将每个方格节点按照方格中的正整数\(x\)拆成\(x\)个顶点. 原来链接方格顶点\(x\)和\(y\)的边增加为\(x \times y\)条边. 由此构成的图\(G'\)仍然是二分图. 这样就等价于求二分图的最大独立集. -
对于图, 我们有:
- 最大独立集 + 最小顶点覆盖 = V
对于二分图, 我们有:
-
所以我们跑一遍Dinic就解决了本题.
10. \(\star\)餐巾计划问题
-
最小费用流, 拆点, 决策分析
-
一个餐厅在连续的\(N\)天中, 每天需要使用的餐巾个数不尽相同. 餐厅每天有三种决策:
- 买一块新餐巾, 代价p
- 旧餐巾送到快洗店, m天后使用, 代价f
- 旧餐巾送到慢洗店, n天后使用, 代价s
设计一个计划使得总花费最小.
-
构造网络\(G\), 每天对应图\(G\)的两个顶点\(X_i\)和\(Y_i\).\(X_i\)表示干净, \(Y_i\)表示脏.
- 顶点\(X_i\)和\(X_{i+1}\)连一条容量为\(\infty\), 费用为\(0\)的边, 表示保留旧餐巾的决策.
- 当\(i+m \leqslant N\)时, 顶点\(X_i\)和\(Y_{i+m}\)连一条容量为\(\infty\), 费用为\(f\)的边, 表示快洗决策.
- 当\(i+n \leqslant N\)时, 顶点\(X_i\)和\(Y_{i+m}\)连一条容量为\(\infty\), 费用为\(s\)的边, 表示慢洗决策.
另外增加源\(s\)和汇\(t\), 以及附加顶点\(k\)
- 从s向每个顶点\(X_i\)连一条边, 容量为第i天餐巾需求量\(r_i\), 费用0.
- 从附加顶点\(k\)向每个顶点\(Y_i\)连一条容量为\(\infty\), 费用为\(p\), 表示购买决策.
- 从顶点\(Y_i\)向\(t\)连一条容量为\(r_i\), 费用为0.
-
求网络\(G\)的最小网络流.
11. 航空路线问题
- 拆点, 费用流
- 给定一个带边权有向图, 求一条从\(s\)到\(t\)又从\(t\)到\(s\)的路径使得:
- 每个点只经过一次
- 每条边只经过一次
- 总权最大
- 这种每个点只能经过一次的显然要拆点建最大流模型, 又因為有边权的设定, 所以我们跑一个最大费用最大流就好了.
12. 软件补丁问题
-
最小转移代价, 最短路
-
某软件有\(n\)个bug, \(m\)个补丁, 每一种补丁都有两个与之对应的bug集合\(B_1[i]\)和\(B_2[i]\), 设当前bug集合为\(S\), 补丁\(i\)可以发挥作用当且仅当
\[S \cup B_1[i] = S \ and\ S \cap B_2[i] = \varnothing \]每个补丁可以修复的bug集合为\(F_1[i]\), 会带来的新bug集合为\(F_2[i]\), 另外, 每个补丁修复都需要一定的时间. 试设计一个算法, 利用\(m\)个补丁把原程序修复成一个没有bug的软件, 并且使得总时间最小.
-
参考文献[2:1]中说这道题可以使用网络流解决, 但在我看来不如使用在隐式图中spfa解决, 具体的, 我们把状态压缩成一个二进制串, 用一个节点表示集合, 这样状态的转移对应了图中的边, 跑一遍spfa就可以解决了.
13. 星际转移问题
-
最大流, 拆点, 利用之前增广结果
-
给定一个有向图, 图上的边周期性开放, 边有费用和容量, 现在求最小代价从\(s\)转移所有人到\(t\).
-
首先考察原问题的反问题: 给定时间\(T\), 最多可以运送多少人?
-
我们把一个点拆成\(T\)个点建图, 如果有一条边\((i,j)\), 那么新图中有一条边\((i, t) \xrightarrow{c(i,j)} (j, t+1)\), 同时, 又有边\((i,t) \xrightarrow{\infty} (i,t+1)\), 那么跑一下最大流就好了.
-
然后考察两种方法: 一种是二分时间\(T\), 一种是从小到大枚举\(T\). 看似二分好一些, 但是第二种方法可以利用之前的结果进行增广, 反而效率会高.
14. 孤岛营救问题
- 分层图最短路
- 题目与黑书[9]上的第61页的题目相同, 来自CTSC 1999
- 建分层图跑一遍spfa就好了.
15. 汽车加油行驶问题
- 分层图最短路
- 设状态为\((x,y,z)\), 以状态为点, 各种决策为边建图, 跑spfa即可.
16. 数字梯形问题
-
费用流
-
给定一个由n 行数字组成的数字梯形如下图所示。梯形的第一行有m 个数字。从梯形的顶部的m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径。
-
规则一: 互不相交: 拆点费用流
-
规则二: 仅在数字处相交: 限制边, 费用流
-
规则三: 允许在数字处相交或边相交: DP
17. 运输问题
- 费用流
- W 公司有m个仓库和n 个零售商店。第i 个仓库有ai个单位的货物;第j 个零售商店需要bj个单位的货物。货物供需平衡,即ai的和=bj的和。从第i 个仓库运送每单位货物到第j个零售商店的费用为cij。试设计一个将仓库中所有货物运送到零售商店的运输方案,
使总运输费用最少。 - 源连仓库流量ai费用0,商店连汇流量bj费用0,每个仓库连每个商店流量无限大费用cij,跑网络流.
18. 分配工作问题
- 有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为cij 。试设计一个将n件工作分配给n个人做的分配方案,使产生的总效益最大。
- 二分图最大权匹配, KM算法.
19. 负载平衡问题
- G公司有\(n\)个环形排列的仓库, 每个仓库存储的货物数量不相等, 如何使用最少搬运量可以使\(n\)个仓库库存数量相同.只能在相邻仓库之间搬运
- 不难发现任意两个仓库之间都可以视为直接搬运. 那么每个仓库的目标就是\(\frac{\sum x_i}n\). 跑费用流就好了.
20. 深海机器人问题
- 给定每个深海机器人的出发位置和目标位置, 以及每条边上生物标本的价值, 计算深海机器人们的最有移动方案使得深海机器人到达目的地后采集到的标本价值最高.
- 把一条边拆成两条边, 第一条边容量为1, 费用为\(c_i\), 第二条边容量为\(\infty\), 费用为0. 建超级源汇, 跑最大费用最大流.
21. \(\star\)最长\(k\)可重区间集问题
-
最大费用流, 最大权不相交路径
-
给定实直线\(L\)上\(n\)个开区间组成的集合\(I\)和一个正整数\(k\), 试设计一个算法, 从\(I\)中选出\(S \subseteq I\), 使得在实直线上的任意一点\(x\), S中包含点\(x\)的开区间个数不超过\(k\), 且\(\sum_{z \in S}|z|\)达到最大, 这样的集合\(S\)称为开区间集合\(I\)的最长\(k\)可重区间集. \(\sum_{z \in S}|z|\)称为最长\(k\)可重区间集的长度.
-
若把每个线段看做点,一组不相交的线段集合就可以看做路径。这样问题就转化为选k条路径使得权值和最大,并且路径不能重叠(一个线段只能选一次)。
-
设给定的开区间集合共有\(m\)个不同的端点. 将这\(m\)个端点从小到大排序为: \(x_1, x_2, \cdots, x_m\), 构造网络\(G=(V,E)\)如下:
- 每个端点\(x_i\)对应一个顶点, 新增源\(s\)和汇\(t\).
- 对于每一个区间\((x_i, x_j)\), 连边\(x_i \xrightarrow {1, x_j-x_i} x_j\).
- 每对顶点\((x_i, x_{i+1})\)若没有边, 则增加一条有向边, 容量为\(k\), 费用为\(0\).
- \(s \xrightarrow{k, 0} x_1\)和\(x_m \xrightarrow{k,0} t\).
求网络的最大费用流.
-
转换思路:端点为点。同样是限制流量。而这次目标针对了【每个点至多出现k次】,而区间则成了一段有价值的点,所以可以端点之间连边来表示。并且这个做法边数更少,更优。
22. 最长\(k\)可重线段集问题
- 基本同21
23. 火星探险问题
- 用一个P*Q 网格表示登陆舱与传送器之间的位置。登陆舱的位置在(X1,Y1)处,传送器的位置在(XP ,YQ)处。登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动。探测车在移动中还必须采集岩石标本。每一块岩石标本由最先遇到它的探测车完成采集。每块岩石标本只能被采集一次。岩石标本被采集后,其他探测车可以从原来岩石标本所在处通过。探测车不能通过有障碍的地面。本题限定探测车只能从登陆处沿着向南或向东的方向朝传送器移动,而且多个探测车可以在同一时间占据同一位置。如果某个探测车在到达传送器以前不能继续前进,则该车所采集的岩石标本将全部损失.给定每个位置的状态,计算探测车的最优移动方案,使到达传送器的探测车的数量最多,而且探测车采集到的岩石标本的数量最多。
- 把每个位置拆成两个点:
- 对于原图中的边, 连\(i' \xrightarrow{\infty ,0} j\)
- 对于岩石顶点, 连\(i \xrightarrow{1,1}i'\)
- 对于每个非障碍顶点, 连\(i \xrightarrow{\infty, 0} i'\).
- \(s \rightarrow\)登陆舱, 容量探测车数, 费用0, 传送器\(\rightarrow t\), 容量探测车数, 费用0
- 最大费用最大流
24. 骑士共存问题
- 二分图最大独立集
- 象棋棋盘上有障碍, 最多能放置多少马使得他们之间不相互攻击.
- 二分图染色, 最大独立集.
\(\mathtt{COPYRIGHT}© \mathtt{2017,KONJAC,MIT\ LICENSE}\)