网络流23(24题 feat 无限之环.)
前置知识#
最大流
费用流
求最大费用流只需要把费用取相反数最后求出费用也取相反数即可。
二分图最大匹配可以最大流做。
二分图最大权匹配可以费用流做。
网络流复杂度都是上界,实际非常玄学。
最大流 = 最小割。
平面图最小割 = 对偶图最短路。
前言#
神 说 : 网络流一堆水紫题.
我显然是不信的.
于是我打算来做做这些经典模型.
为啥只做 23 题? 因为 "机器人路径规划问题" 是著名的假题但是搜索可过
有人写 A* 有人写暴力,似乎还有人证明有 的算法……
建议改为网络流23题.
加一个无限之环正好凑够24题.
以下排列顺序除无限之环外按照洛谷题号.
为了简便表示,以下文字描述中 :
向 连 ,表示向点 连一条容量为 的边.
向 连 ,表示向点 连一条容量为 且单位流量费用为 的边.
餐巾计划问题#
令 表示第 天需要的餐巾数.
首先发现天数很小,考虑对于天数开点.
餐巾有的个数和代价是分开计算的,不同的方式代价是不同的,需要最小化代价,考虑最小费用最大流.
一天有需要得到的干净餐巾和产生的脏餐巾,现有的餐巾不需要保证全部清洁,只需要有足够多就行,符合流的特性.
首先考虑一天有需求餐巾和产生脏餐巾两部分,考虑每天拆两个点,分别记为 : ,和 .
源点向每个 连 ,代表产生 条脏的餐巾.
每个 向汇点 连 ,代表获得 条干净餐巾.
餐巾可以放着不洗, 向 连
餐巾可以慢洗, 向 连
餐巾可以快洗, 向 连
餐巾可以直接买,源点向每个 连
星际转移问题#
首先并查集特判无解。
参照餐巾计划,把每个时刻的每个位置都建一个点。
然后每次增加一层后增广一下,直到最大流超过人数 即可。
飞行员配对方案问题#
二分图匹配裸题,边满流即匹配上.
源点连左集合每个点
每个匹配关系左连右
右集合每个点连汇点
软件补丁问题#
很有意思的最短路题,和网络流没有任何关系.
首先状压 bug 被修复的情况,然后打补丁转化为有向图上移动.
直接建边显然存不下,那么考虑最短路松弛的时候直接枚举结点然后检查这两个点是否有边相连即可.
太空飞行计划问题#
求最大收益就是最小化损失.
考虑如何变最小割.
首先建图的时候连负的容量显然就是假做法,不能这样实现一边花钱一边赚钱.
于是先假设能赚到使所有的钱,然后把赚不到的去掉.
其实就是最大权闭合子图.
最大权 = 权值和 - s-t最小割
但是这个题输入格式非常恶臭,令人不想写。
试题库问题#
题型建 个点,题目建 个点.
从源点向每个题目连 .
从题目向其所属的题型连 .
从题型向汇点连需要这种题型的题数.
最大流为 即为有解.
最小路径覆盖问题#
最小点覆盖 = 顶点数 - 最大匹配.
最大独立集 = 顶点数 - 最小点覆盖.
要求路径最少,每个点只能用一次,路径有向.
将每个点拆成入点和出点,将出点匹配到入点,可以发现有最多的匹配时就是将尽可能多的点合成链.
然后就暴力输出一下即可.
魔术球问题#
贪心题.
每个球只有一个,放在当前能放的位置总是比新开一个好.
最长不下降子序列问题#
首先第一问 DP 即可。
第二问每个数只能选一次,考虑拆点。
然后考虑长度限制,这里可以使用第一问 DP 用的数组,回顾 DP 状态设计, 表示严格以第 位结束的 LIS 最长长度,于是对于 可以视作一个终点, 可以视作一个起点,然后只有 这样的可以连边。
然后是第三问,把 和 的限制摘掉即可。
航空路线问题#
人生苦短,我用 std::string
和 __gnu_pbds::gp_hash_table
。
依然是只经过一次,依然是流量限制,依然是拆点。
然后是经过城市尽量多,可以费用流。
啥?返回路径?那就起点出去两个路径就完事了。
方案就简简单单 DFS 一下即可。
方格取数问题#
已经做过类似模型的了.
最大化获取,考虑最小化失去.
首先考虑到相邻,先黑白染色.
然后与源/汇点割开就是放弃那一部分的代价.
方格中间的部分不能割,流量无限大.
圆桌问题#
每个桌代表的来源不能重复,即边有流量限制.
源点向每个单位连
每个单位向每张桌子连
每张桌子向汇点连
最大流为 ,即为有解.
骑士共存问题#
和方格取数一样.
发现在黑白染色后,一个骑士支配点颜色都与这个骑士所在点颜色不同.
然后就是向支配点连无限容量的边,每个点贡献都是 1.
求最小割就是最小损失代价,那么答案为 :
火星探险问题#
待补.
最长k可重线段集问题#
待补.
最长k可重区间集问题#
待补.
汽车加油行驶问题#
BFS和最短路都能过的屑费用流.
待补费用流做法.
孤岛营救问题#
状压 + BFS.
待补.
深海机器人问题#
待补.
数字梯形问题#
待补.
分配问题#
二分图最大权匹配.
裸的最小费用流和最大费用流.
运输问题#
建图方法写在题面了,不解释.
源点往仓库连
仓库往零售店连
零售店往汇点连
负载平衡问题#
这就是一道贪心.
即使可以用网络流的方法求解,但是时间最优的方法就是贪心.
做法和图论或者网络流建模无关,不写了.
无限之环#
神题.
首先对于一这个的游戏,明显不能把一个方格作为单一的结点,这样不能体现出15种格子的不同。
由于最终局面是所有管道连接形成环流,所以建图明显不能直接模拟管道的形态。
考虑把矩阵黑白染色,也就是染成类似国际象棋的棋盘那样,使得没有两个黑格子/两个白格子相邻。这个技巧可以在骑士共存问题里见到。
那么考虑最终局面,先假设其有解,那么每个水管的接口都是接上的,而且每个格子的水管都要靠接到四周的水管来达到平衡。
那么黑白染色就有用了啊。
对于黑格子,考虑将其作为流入的结点,有几个管口就从源点流过去多少流量。
那么黑格子四周的白格子就要让这些流量流到汇点,每个白格子可以承担管口数的流量,从白格子连一条边到汇点,流量是这个格子的管口数。
现在考虑如何通过建图求得是否有解。
首先根据黑白染色,有:
黑格的管口数总和 = 白格的管口数总和
如果不相等,那么必定无解。
然后考虑一个格子反映在图上该怎么办,一个结点不足以表示格子的全部状态,考虑拆点。
一个格子的流量来去有5种,
来/去上面,
来/去下面,
来/去左面,
来/去右面,
从源点来/到汇点去。
于是把一个格子拆成5个点。
上下左右四个点代表和周围的格子的来往,中间的点代表这个格子流量的来源/去向。
那么源点向黑格子的中结点连边,白格子的中结点向汇点连边。
一个格子的左结点向其左侧结点的右结点连边,当且仅当这是白格子,因为如果在黑格子也连边,这条边是重复的,但是在跑费用流的时候这条重边会出事。
考虑不同的格子模式:
单点型#
指上图左侧除了中间两个的四个方格。
把有水管那一面叫做正面。
特点是转到侧面要1的代价,转到后面需要2的代价。
画个图:
对于头在右边的情况
流量到右边(原来的方向)显然不需要付出代价,到上下都只需要转1次,到左边转两次,于是边权分别是1,1,2.
直角形#
上图右边四个角的方格。
还是对于原来的流动方向连代价为0的边,考虑如何把流量引导到别的位置才能分别对应转90°和180°的情况。
假设是从上面连到右面这么一个直角。
需要满足四种情况:
流量走到上面和右面,不付出代价
流量走到上面和左面,付出1的代价
流量走到下面和左面,付出1的代价
流量走到下面和右面,付出2的代价
并且满足
流量不能同时到上面和下面,
流量不能同时到左面和右面。
可以发现需要满足的四种情况有:
每有一个流量的方向被翻转(从左到右,从上到下),付出1的代价。
那么从上节点向下结点连边,右结点向左节点连边即可。
如图。
T字型#
考虑上,下,右有连接的T字型方格。
这个就没什么限制了,随便选三个方向都可以通过旋转得到。
继续分类讨论:
流量流到上下右,代价0
流量流到上左右,代价1
流量流到下左右,代价1
流量流到上下左,代价2
发现只有在把右侧流量转到左侧时才付出2代价,转移上面和下面的到左侧都只需要1代价。
建图如下:
直线型和十字型#
一个题干要求不能转,一个转了和没转每区别,不考虑连有代价的边。
判断是否有解与求最小代价#
判断条件有二。
-
1.之前提到的 黑格子流量和等于白格子流量和
-
2.最大流等于黑格子流量和/白格子流量和
以及最小代价,这个在跑费用流的过程中也求出来了。
作者:AstatineAi
出处:https://www.cnblogs.com/AstatineAi/p/network-flow-23-probs.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现