[hihoCoder] #1093 : 最短路径·三:SPFA算法
时间限制: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 }