PKUSC 2024 最短路径
本文首发于 QOJ https://qoj.ac/blog/skip2004/blog/866
大家好,我是钱哥,我来写一下 PKUSC2024 最短路径 的题解。没有做过这个题的同学可以先自行做一做。
我们下面来讲解一下如何一步步解决这个题目。
subtask 4
首先,我们来解决第一个具有挑战性的子任务:
大家来发挥一下想象力,由一个点
在这个题上,我们可以执行双向 dijkstra,由
当两个点的 dijkstra 相遇了,我们找到了最短路吗?很可惜,并没有。

我们发现,即使两边的 dijkstra 相遇在了
好在,我们简单分析一下,我们可以发现两边相遇过后,最多有一条不在最短路上的边。因此,我们可以枚举一侧的点,枚举它的出边,找到所有可能的路径。
现在我们来分析一下我们算法的复杂度,假设我们双向 dijkstra 一共访问了
那么问题来了,
双向 dijkstra
我们来分析一下 dijkstra 的行为:
q.emplace(0, S); while (!q.empty()) { auto [d, u] = q.top(); q.pop(); if (dis[u] != -1) continue; dis[u] = d; for (auto [v, w] : e[u]) { q.emplace(d + w, v); } }
这份 dijkstra 可能和大家写法并不完全相同,但是完全可以看出是正确的 dijkstra。我们其实可以看到,每条边的目标点,事实上只有在第
如果你仔细思考一下,你会发现,在双向 dijkstra 相遇之前,事实上两边也是互相独立的。因此,这个过程就像生日悖论一样,如果每次扩展最短路树上点少的一侧,期望只要扩展
除此之外,我们可以发现,最短路树的点之间的所有边也是
让我们回到 subtask 4,我们可以发现,此时这个算法的时间复杂度大约为
subtask 2
相信你发现了,上面的算法甚至没有办法通过子任务
如果你做过
你也许想问,到这里,我们还是没有解决枚举中间边的复杂度,事实上,这个子任务我们只要跑单向 dijkstra 就可以了(×),因为每次到的点是独立均匀随机的,因此只有期望 )。
最终算法
下面我们要迎接我们的最终算法了,非常精彩!
我们现在已经可以用
我们考虑一下这条路径:
那么边权
如果你只想感性理解,这里就结束了,时间复杂度为
证明
定理:我们有至少
证明:
对于一对固定的
如果
根据 Union Bound,我们可以得知,所有
这个证明多带了一个
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】