首页 > 技术文章 > [hihoCoder] #1093 : 最短路径·三:SPFA算法

easonliu 2015-04-08 15:57 原文

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋!

鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路。

不过这个鬼屋虽然很大,但是其中的道路并不算多,所以小Hi还是希望能够知道从入口到出口的最短距离是多少?

提示:Super Programming Festival Algorithm。

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为4个整数N、M、S、T,分别表示鬼屋中地点的个数和道路的条数,入口(也是一个地点)的编号,出口(同样也是一个地点)的编号。

接下来的M行,每行描述一条道路:其中的第i行为三个整数u_i, v_i, length_i,表明在编号为u_i的地点和编号为v_i的地点之间有一条长度为length_i的道路。

对于100%的数据,满足N<=10^5,M<=10^6, 1 <= length_i <= 10^3, 1 <= S, T <= N, 且S不等于T。

对于100%的数据,满足小Hi和小Ho总是有办法从入口通过地图上标注出来的道路到达出口。

输出

对于每组测试数据,输出一个整数Ans,表示那么小Hi和小Ho为了走出鬼屋至少要走的路程。

样例输入
5 10 3 5
1 2 997
2 3 505
3 4 118
4 5 54
3 5 480
3 4 796
5 2 794
2 5 146
5 4 604
2 5 63
样例输出
172

 

 1 #include <iostream>
 2 #include <vector>
 3 #include <queue>
 4 #include <algorithm>
 5 #include <climits>
 6 using namespace std;
 7 
 8 const int INF = 1e9;
 9 
10 struct node {
11     int idx;
12     int len;
13     node(int _idx = 0, int _len = 0) : idx(_idx), len(_len){}
14 };
15 
16 int N, M, S, T;
17 vector<vector<node>> graph;
18 vector<int> dist;
19 
20 void solve() {
21     vector<int> visit(N+1, false);
22     //priority_queue<int, vector<int>, greater<int>> heap;
23     queue<int> heap;
24     dist[S] = 0;
25     heap.push(S);
26     visit[S] = true;
27     while (!heap.empty()) {
28         //int u = heap.top();
29         int u = heap.front();
30         heap.pop();
31         visit[u] = false;
32         for (int i = 0; i < graph[u].size(); ++i) {
33             int v = graph[u][i].idx;
34             if (dist[v] > dist[u] + graph[u][i].len) {
35                 dist[v] = dist[u] + graph[u][i].len;
36                 if (!visit[v]) {
37                     heap.push(v);
38                     visit[v] = true;
39                 }
40             }
41         }
42     }
43     cout << dist[T] << endl;
44 }
45 
46 int main() {
47     while (cin >> N >> M >> S >> T) {
48         graph.assign(N+1, vector<node>(0));
49         dist.assign(N+1, INF);
50         int u, v, len;
51         for (int i = 1; i <= M; ++i) {
52             cin >> u >> v >> len;
53             graph[u].push_back(node(v, len));
54             graph[v].push_back(node(u, len));
55         }
56         solve();
57     }
58     return 0;
59 }

 堆优化的Dijkstra算法。总体来说还是SPFA算法更好写一点。不过Dijsktra算法可以提前输出,只到轮到点T,直接输出即可。

 1 #include <iostream>
 2 #include <vector>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int INF = 1e9;
 8 
 9 struct edge {
10     int idx;
11     int dist;
12     edge(int _idx, int _dist) : idx(_idx), dist(_dist) {}
13 };
14 
15 struct cmp {
16     bool operator () (const edge &a, const edge &b) { return a.dist > b.dist; }
17 };
18 
19 int N, M, S, T;
20 vector<vector<edge>> graph;
21 
22 void solve() {
23     priority_queue<edge, vector<edge>, cmp> heap;
24     vector<int> dist(N + 1, INF);
25     vector<bool> visit(N + 1, false);
26     dist[S] = 0;
27     visit[S] = true;
28     for (int i = 0; i < graph[S].size(); ++i) {
29         auto v = graph[S][i];
30         dist[v.idx] = min(dist[v.idx], v.dist);
31         heap.push(edge(v.idx, dist[v.idx]));
32     }
33     while (!heap.empty()) {
34         auto u = heap.top();
35         heap.pop();
36         if (u.idx == T) {
37             cout << u.dist << endl;
38             return;
39         }
40         if (visit[u.idx]) continue;
41         visit[u.idx] = true;
42         for (int i = 0; i < graph[u.idx].size(); ++i) {
43             auto v = graph[u.idx][i];
44             if (!visit[v.idx] && dist[v.idx] > dist[u.idx] + v.dist) {
45                 dist[v.idx] = dist[u.idx] + v.dist;
46                 heap.push(edge(v.idx, dist[v.idx]));
47             }
48         }
49     }
50     cout << "-1" << endl;
51 }
52 
53 int main() {
54     while (cin >> N >> M >> S >> T) {
55         int u, v, len;
56         graph.resize(N + 1);
57         for (int i = 0; i < M; ++i) {
58             cin >> u >> v >> len;
59             graph[u].push_back(edge(v, len));
60             graph[v].push_back(edge(u, len));
61         }
62         solve();
63     }
64     return 0;
65 }

 

推荐阅读