SPFA算法模板

Posted R o b i n

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPFA算法模板相关的知识,希望对你有一定的参考价值。

SPFA是队列优化后的Bellman-Ford,用于求带负权边的最短路,然而传说中O(k*n)的复杂度好像是错误的。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 #include<set>
 6 #include<queue>
 7 using namespace std;
 8 #define INF 0x3f3f3f3f
 9 #define M(a, b) memset(a, b, sizeof(a))
10 const int maxn = 1000 + 5;
11 
12 struct Edge {
13     int from, to, dist;
14 };
15 
16 struct SPFA {
17     int d[maxn], cnt[maxn], p[maxn];
18     int n, m;
19     bool inq[maxn];
20     vector<int> G[maxn];
21     vector<Edge> edges;
22 
23     void init(int n) {
24         this->n = n;
25         for (int i = 1; i <= n; ++i) G[i].clear();
26         edges.clear();
27     }
28 
29     void AddEdge(int from, int to, int dist) {
30         edges.push_back(Edge{from, to, dist});
31         int m = edges.size();
32         G[from].push_back(m-1);
33     }
34 
35     bool spfa(int s) {
36         M(d, INF); M(cnt, 0); M(inq, 0);
37         d[s] = 0;
38         queue<int> q;
39         q.push(s);
40         inq[s] = true;
41         while (!q.empty()) {
42             int u = q.front(); q.pop();
43             inq[u] = false;
44             for (int i = 0; i < G[u].size(); ++i) {
45                 Edge &e = edges[G[u][i]];
46                 if (d[e.to] > d[u] + e.dist) {
47                     d[e.to] = d[u] + e.dist;
48                     p[e.to] = G[u][i];
49                     if (!inq[e.to]) {
50                         q.push(e.to); inq[e.to] = true; 
51                         if (++cnt[e.to] > n) return false;
52                     }
53                 }
54             }
55         }
56         return true;
57     }
58 
59 };
60 
61 SPFA solver;
62 
63 int main() {
64     int n, m, a, b, c;
65     while(cin >> m >> n) {
66         solver.init(n);
67         while(m--) {
68             cin >> a >> b >> c;
69             solver.AddEdge(a, b, c);
70             solver.AddEdge(b, a, c);
71         }
72         solver.spfa(1);
73         cout << solver.d[n] << endl;
74     }
75     return 0;
76 }

 

以上是关于SPFA算法模板的主要内容,如果未能解决你的问题,请参考以下文章

SPFA算法模板

hdoj2544 最短路(Dijkstra || Floyd || SPFA)

Spfa算法模板

最短路算法 -- SPFA模板

洛谷 P5960 模板差分约束算法(spfa)

算法模板之SPFA