Dijkstra 最短路笔记

前言

前两天新阵地联盟的 T15 出了个自己发明的 Dijkstra,然后我非常开心地没有拿到分数。于是打算重写笔记。


Dijkstra 是由 E.W.Dijkstra 发明的,用于求非负权图上的单源最短路算法。

算法过程

Dijkstra 的想法很简单。要求 \(s\) 到 \(t\) 的最短路,我们一开始令 \(dis_s = 0\),其他点的 \(dis\) 为 \(+ \infty\)(一般在 OI 中,我们令其为 0x3f3f3f3f)。

然后从 \(s\) 开始跑 bfs,对于每个结点 \(u\),我们遍历其下一个结点 \(v\),其中 \(w\) 为 \(u\) 到 \(v\) 的边权,如果 \(dis_v > dis_u + w\),那么我们对 \(v\) 进行松弛操作。并且将结点 \(v\) 放入以 \(dis\) 排序的小根堆中。

正确性证明

由于我不会,证毕。

时间复杂度

使用堆优化后,平均时间复杂度为 \(O(m \log m)\)。

朴素算法下时间复杂度为 \(O(n^2)\)

示例代码

Python

# 我们已经用链式前向星把图存在了 g[] 中,head[] 为每个结点的边所在链表的头指针,规定 g[] = [v, w, nxt],其中 nxt = 0 表示空指针
# 使用 dis 储存到每个结点的距离,初始时已经初始化为 0x3f3f3f3f
import heapq
from collections import defaultdict

def dijkstra(st, ed):
    dis = defaultdict(lambda: float('inf'))
    dis[st] = 0
    q = [(0, st)]
    vis = set()
    while q:
        _, u = heapq.heappop(q)
        if u in vis:
            continue
        vis.add(u)
        cur = head[u]
        while cur:
            v, w, nxt = g[cur]
            if dis[v] > dis[u] + w:
                dis[v] = dis[u] + w
                heapq.heappush(q, (dis[v], v))
            cur = nxt
        return dis[ed]
posted @ 2026-10-13 10:42  Hanatomizu  阅读(6)  评论(0)    收藏  举报