思路解析
问题本质
红球从节点 1 出发,蓝球从节点 i 出发,两球沿有向边移动,目标是找一个汇合点 t,使得:
mint(dist(1tot)+dist(i→t))min_t \big(\text{dist}(1 to t) + \text{dist}(i \to t)\big) mint (dist(1tot)+dist(i→t))
核心难点
对每个 i(2~n),暴力做法需要跑 n-1 次 Dijkstra,时间不可接受。
建图技巧——分层图
构造一个 2n 个节点的增广图(两层):
* 第 1 层(节点 1~n):保留原图的有向边,代表红球的移动。
* 第 2 层(节点 1'~n',编号 n+1~2n):将原图所有边反向,代表蓝球的"逆向回溯"。
* 跨层桥边:对每个节点 t,加一条 t → t'(代价 0)的边。
然后从节点 1 跑一次 Dijkstra,到节点 i'(即 i+n)的最短路就是答案。
为什么正确?
从节点 1 出发,在第 1 层走到某个 t,花费 dist(1→t);然后走桥边到 t'(代价 0);接着在第 2 层(反向图)从 t' 走到 i',等价于在原图中从 i 走到 t,花费 dist(i→t)。Dijkstra 自动取所有 t 中的最小值。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
逐行注释代码
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------