先用倍增判断哪些点对之间存在长度恰好为 2^k 的路径,再把这些点对压成 1 秒边求最短路。
P1613 跑路
GESP8 冲刺课堂页:先建模,再压缩状态,最后读代码。
一、先回答问题
直接求原图最短边数后拆二进制不对,因为每一段必须在图上真的能连续走通。
二、核心观察
can[i][j][k] 表示 i 到 j 存在长度恰好 2^k 的路径。
为什么不丢答案:一秒能走的正是一段 2 的幂长度路径,把每段压成边权 1 后,最少秒数就是新图最短路。
can[i][j][k]
中转 t
新图距离
三、互动演示
步骤1
关键状态 A-
关键状态 B-
答案/目标-
复杂度看表
课堂动作手推
点击下一步开始。
四、自己选答案
can 的含义是什么?
先判断,再点按钮。
最后为什么用 Floyd?
先判断,再点按钮。
五、手推结果
| 层 | 判断方式 | 压缩结果 |
|---|---|---|
| k=0 | 原图一条边 | 一秒边 |
| k>0 | i->t 与 t->j 拼接 | 仍是一秒边 |
| 最后 | 新图最短路 | 最少秒数 |
课堂要求:每题先说清对象、关系、保留的信息、压缩掉的信息,再写代码。
六、C++14 参考代码
can[i][j][k] = true
if can[i][t][k - 1] && can[t][j][k - 1]