1 条题解
-
0
题解:
一、问题转化 我们有一个 行 列的网格。每个格子可能是空地('.')、羊('S')或狼('W')。羊有且仅有一只,且与羊相邻的格子中没有狼。我们可以支付 金币消灭一只狼(将 'W' 变为 '.'),或支付 金币在一个空格子上挖壕沟(该格子狼无法通过)。目标是使所有狼都无法到达羊所在格子,求最小总花费。
这等价于:在一个点带权的网格图中,删除一些点(消灭狼或挖壕沟),使得所有狼所在的点与羊所在的点不连通。删除一个狼点花费 ,删除一个空点花费 ,羊点不可删除。求满足条件的最小删除总代价。这是一个经典的最小点割问题。
二、最小点割模型 我们将原网格转化为一个容量网络(流网络),利用最大流最小割定理求解。
对于每个格子 ,将其拆为入点 和出点 ,并连一条有向边 ,容量为删除该格子的代价:
- 若格子为狼('W'),容量为 ;
- 若格子为空('.'),容量为 ;
- 若格子为羊('S'),容量为 (不可删除)。
对于网格中相邻的两个格子 (共享一条边),添加两条无穷大容量的边: 和 ,表示狼可以在相邻格子间自由移动(只要目标点未被删除)。
建立超级源点 和超级汇点 :
- 向每个狼格子的入点 连一条容量为 的边,表示所有狼初始都是威胁来源;
- 羊的出点 (羊所在格子拆出的出点)向 连一条容量为 的边,表示羊是我们要保护的目标。
在这个网络中,一个 - 割对应一种删除方案:被割断的 边表示该格子被删除(花费其容量)。割的容量就是总花费。由于羊的入出边容量为 ,它永远不会被割断(不可删除)。狼的入边 为 ,所以割不会选择这些边,而是选择删除狼点本身()或删除其他中间空格。因此,最小割的容量即为保证狼与羊不连通的最小花费。
三、算法实现 我们使用 Dinic 算法求最大流。由于网络中的边权较大(可达 ),使用 64 位整数(long long)存储流量。
建图步骤:
- 给每个格子编号 (行 ,列 )。设总格点数 。
- 拆点:入点编号为 ,出点编号为 。超级源 ,超级汇 。总点数 。
- 对于每个格子:
- 若是 'S':加边 ,容量 INF;
- 若是 'W':加边 ,容量 ;同时加边 ,容量 INF;
- 若是 '.':加边 ,容量 。
- 对于每个格子,遍历其四个方向邻居(上下左右),若邻居在界内,加边 ,容量 INF。
- 找到羊所在的格子,设其出点为 ,加边 ,容量 INF。
- 执行 Dinic 计算 到 的最大流,即为答案。
正确性:由最小割最大流定理,网络的最大流等于最小割的容量。上述网络的 - 割与合法的删除方案一一对应,且割的容量等于总花费。注意到题目保证羊的相邻格子没有狼,这确保了初始状态下不会出现狼与羊直接相邻导致必须割 或 的边(容量无穷)的情况,从而保证最小割有限。
四、复杂度分析
- 点数量:,对于所有测试用例 ,总点数 。
- 边数量:每个格子内部边 条,源汇相关边 ,相邻边(双向)至多约 条,总数 。所有测试用例总边数 级别。
- Dinic 算法在网格图上的实际运行效率很高,虽然理论上界为 ,但远无法达到。在 下足以在 秒内通过。
- 1
信息
- ID
- 7249
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者