写这篇博客,主要是为了记录一下做网络流24题中几道有价值的题目。个人感觉网络流写法并不是主要难点,难在建模和问题的转化上。
最小路径覆盖问题
TP
二分图匹配问题。题目既然要求最少的路径覆盖,那么转化一下问题,最小的路径覆盖就是让越多的点相连通。因为是“简单路”并且是有向的,所以不难想到用二分图匹配的做法来求出最多的可以连上的边。
最后的答案就是 总点数 - 最大匹配数。二分图匹配问题可以用网络流解决。
Code:
数字梯形
TP
比较经典的关于建模思维的题目。
题目大意是,给出一个梯形,要根据下列要求,求m条从顶到底的路径的最大的权和。
- 从梯形的顶至底的 m 条路径互不相交;
- 从梯形的顶至底的 m 条路径仅在数字结点处相交;
- 从梯形的顶至底的 m 条路径允许在数字结点相交或边相交。
问题就在于如何将这三个子问题转换为网络流模型。
网络流的建模,拆点可能是最有用的方法了。我们将每一个点拆成两个(小)点\(x_i, y_i\) 并连边,容量随子任务要求不同而不同,费用始终为这个点的权值;对于梯形上下点之间的连边,总是用\(y_i\)去连接\(x_j\) ,容量随子任务要求不同而不同, 费用始终为0。用一个超级源点连接顶层,容量只能为1(按照题目要求),费用总为0;一个超级汇点承接底层,容量随子任务要求不同而不同,费用总为0。
对于子任务1,m条路径互不相交,即点、边均不能有重复。那么就将\(x_i, y_i\)之间连一条容量为1的边,这样就会防止点相交。而对于边,为了不让其相交,我们可以将梯形上下点的连边的容量修改为1,边即可无交。超级根与梯形的所有连边容量都必须是1.
对于子任务2,类比子任务1,允许在数字结点处相交即意味着\(x_i, y_i\)之间的容量可以为无限大,这样就允许了点重合。超级汇点与梯形底层所连接的所有边容量设置为无穷大。
对于子任务3,类比前两个任务,只需要将梯形上下的边的容量也修改成无穷大就OK。
Code:
题目要求的是最大费用流,只用把原边权值改为负然后最后答案改为负就OK。
星际转移
TP
这应该是最有价值的一题。在大佬们的启发下我终于有了思路…
题目的一个难点就是太空船是周期性停靠的。
正解是写不出来的,这辈子都写不出正解的。复杂的数据结构和数学又不会,就是枚举和暴力这种东西,才能勉强A几道水题。
大致思路:按照天数加边,求分层图最大流的每天的累加直到答案为人数(因为网络流的特性就是图有加边不用重构只用在原基础上增广)。每过一天多一层。注意一下,因为人员可以“滞留”,所以这一天的星球/空间站要和下一天的星球/空间站连边,容量无限。至于如何表达在不同天数下的各星球状态,只用采用一种方法让其不重复就OK。如果有信心随机都没问题,反正又不追加查询
Code:
疏漏错误请评论。
xD.