Skip to content

WARNING

🧪 Beta公测版本提示:教程主体已完成,正在优化细节,欢迎大家提Issue反馈问题或建议。

algo07 最短路径 — demo.py 代码详解

Download demo.py

运行方式

bash
cd docs/algorithms/graph/shortest-path/code
python demo.py

代码结构

函数算法复杂度特点
dijkstra()Dijkstra堆优化O((V+E)log V)非负权图
bellman_ford()Bellman-FordO(VE)负权+负环检测
spfa()SPFAO(kE) 平均队列优化版BF
floyd_warshall()Floyd-WarshallO(V³)全源最短路径
a_star()A*启发式带方向搜索

第1步:Dijkstra 的正确性关键

python
if d > dist[u]:
    continue  # 过时条目,跳过!

这行代码至关重要。因为堆中可能存储了同一个顶点在不同时刻的距离。当弹出一个 (d,u) 时,d 可能已经不是 u 当前的最短距离了。

第2步:松弛操作的本质

if dist[u] + w < dist[v]:
    dist[v] = dist[u] + w

松弛是所有最短路径算法的核心操作。它检查"绕道"(经过新的顶点)是否能缩短已有路径。Dijkstra 贪心选择下一个要用的源是什么,Bellman-Ford 重复松弛所有边。

第3步:Floyd-Warshall 为何 k 在最外层?

python
for k in range(n):      # 第 k 阶段:允许经过前 k 个顶点
    for i in range(n):
        for j in range(n):
            dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])

DP 定义:dp[k][i][j] = 只允许经过顶点 0..kij 的最短距离。k 代表 DP 阶段的推进,必须放在最外层。

关键概念速查表

算法贪心/DP数据结构允许负权检测负环全源
Dijkstra贪心优先队列
Bellman-FordDP边列表
SPFA贪婪+队列队列
Floyd-WarshallDP矩阵否(检测对角)
A*启发式贪心优先队列

源码位置

clone 后打开(相对仓库根目录):

docs/algorithms/graph/shortest-path/code/demo.py