Course 可以參考我做的課程簡報:
MST & Shortest Path
Shortest Path Faster Algorithm (SPFA) 單源最短路徑 利用 queue 加速的 Bellman-Ford,僅對需要的邊做鬆弛 枚舉起點鬆弛過的邊,而鬆弛過的點除非被重新鬆弛,否則不會更動
生成步驟
從起點開始推入佇列,根據佇列中的點 a 與其相連的點 b 是否可鬆弛
( b 原本與根的距離 dist[b]
比從根經過 a 再到 b dist[a] + w[a][b]
還大)
更新根到 b 的距離 dist[b]
為 dist[a] + w[a][b]
將點 b 推入佇列
SPFA Example
Template 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include <bits/stdc++.h> using namespace std;const int maxn = 2000 +5 ;const int INF = 0x3f3f3f3f ;struct Edge { int v; int w; }; int N, M;vector<Edge> G[maxn]; bool SPFA (int S) { int cnt[maxn]; int dist[maxn]; bool inqueue[maxn]; queue<int > q; memset (cnt, 0 , sizeof (cnt)); memset (dist, INF, sizeof (dist)); memset (inqueue, false , sizeof (inqueue)); q.push (S); dist[S] = 0 ; inqueue[S] = true ; cnt[S] = 1 ; while (!q.empty ()){ int now = q.front (); q.pop (); inqueue[now] = false ; for (auto &e : G[now]){ if (dist[e.v] > dist[now] + e.w){ dist[e.v] = dist[now] + e.w; if (!inqueue[e.v]){ if (++cnt[e.v] >= N) return false ; q.push (e.v); inqueue[e.v] = true ; } } } } return true ; } int main () { int t; cin >> t; while (t--){ cin >> N >> M; for (int i = 0 ; i <= N; ++i) G[i].clear (); int u, v, w; for (int i = 0 ; i < M; ++i){ cin >> u >> v >> w; G[u].push_back ({v, w}); } if (!SPFA (0 )) cout << "possible" << endl; else cout << "not possible" << endl; } }
UVA Problem UVA00558 - Wormholes