SPFA 最短路

进阶

SPFA 是 Bellman-Ford 的队列优化版本,平均 O(E),最坏 O(VE)。

SPFA 最短路

演示 SPFA(队列优化的 Bellman-Ford)求最短路的过程。

AlgoAnim · SPFA 最短路

待机

速度
待机
// 源代码
1bool spfa(int src, int V, vector<vector<pair<int,int>>>& adj, vector<long long>& dist) {
2    dist.assign(V, LLONG_MAX);
3    vector<int> cnt(V, 0);
4    vector<bool> inQueue(V, false);
5    queue<int> q;
6    dist[src] = 0;
7    q.push(src);
8    inQueue[src] = true;
9    while (!q.empty()) {
10        int u = q.front(); q.pop();
11        inQueue[u] = false;
12        for (auto [v, w] : adj[u]) {
13            if (dist[u] + w < dist[v]) {
14                dist[v] = dist[u] + w;
15                if (!inQueue[v]) {
16                    q.push(v);
17                    inQueue[v] = true;
18                    if (++cnt[v] > V) return false;
19                }
20            }
21        }
22    }
23    return true;
24}

复杂度分析

时间 平均 O(E), 最坏 O(VE)
空间 O(V)
最优 O(E)
最坏 O(VE)

算法讲解

SPFA 用队列维护待松弛的节点,每次取出队首节点松弛其邻居。

如果邻居距离被更新且不在队列中,则加入队列。

可以检测负权环:如果某个节点入队次数超过 V 次,则存在负环。

平均复杂度 O(E),但最坏情况仍为 O(VE)。