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 }