Who's Studio.

hihoCoder#1093 - SPFA算法

Word count: 453Reading time: 2 min
2016/05/16

题目

给定一个无向图,两个顶点之间可能有多条边,求顶点1到顶点N的最短路径。给定的图中边的数量较少。
具体描述请见hihoCoder

解题思路

SPFA算法,即Shortest Path Faster Algorithm。对图进行广度优先搜索,并且在搜索的过程中实时更新所有顶点到顶点1的最短距离。具体来说,是在一个顶点出队时查看它的所有邻接顶点,并更新它们的最短距离,如果它们不在队列中则入队。

时间复杂度

时间复杂度为O(kE),k是个比较小的系数(并且在绝大多数的图中,k<=2,然而在一些精心构造的图中可能会上升到很高)(摘自维基百科)。

代码

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
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Node {
int d = -1;
bool inQueue = false;
vector<Node*> neighbors;
vector<int> edges;
};

int spfa(Node* graph, int s, int t) {
Node* S = graph + s;
S->d = 0;
queue<Node*> queue;
queue.push(S);
while (!queue.empty()) {
Node* cur = queue.front();
cur->inQueue = false;
queue.pop();
for (int i = 0; i < cur->neighbors.size(); i++) {
if (cur->neighbors[i]->d == -1 || cur->neighbors[i]->d > cur->d + cur->edges[i]) {
cur->neighbors[i]->d = cur->d + cur->edges[i];
if (!cur->neighbors[i]->inQueue) {
cur->neighbors[i]->inQueue = true;
queue.push(cur->neighbors[i]);
}
}
}
}

return graph[t].d;
}

int main() {
int N = 0, M = 0, S = 0, T = 0;
cin >> N >> M >> S >> T;
Node* graph = new Node[N + 1];
for (int i = 0; i < M; i++) {
int a = 0, b = 0, edge = 0;
cin >> a >> b >> edge;
graph[a].neighbors.push_back(graph + b);
graph[a].edges.push_back(edge);
graph[b].neighbors.push_back(graph + a);
graph[b].edges.push_back(edge);
}

cout << spfa(graph, S, T) << endl;

return 0;
}
CATALOG
  1. 1. 题目
  2. 2. 解题思路
  3. 3. 时间复杂度
  4. 4. 代码