1111 Online Map
Posted ruruozhenhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1111 Online Map相关的知识,希望对你有一定的参考价值。
Input our current position and a destination, an online map can recommend several paths. Now your job is to recommend two paths to your user: one is the shortest, and the other is the fastest. It is guaranteed that a path exists for any request.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers N (2), and M, being the total number of streets intersections on a map, and the number of streets, respectively. Then M lines follow, each describes a street in the format:
V1 V2 one-way length time
where V1
and V2
are the indices (from 0 to N−1) of the two ends of the street; one-way
is 1 if the street is one-way from V1
to V2
, or 0 if not; length
is the length of the street; and time
is the time taken to pass the street.
Finally a pair of source and destination is given.
Output Specification:
For each case, first print the shortest path from the source to the destination with distance D
in the format:
Distance = D: source -> v1 -> ... -> destination
Then in the next line print the fastest path with total time T
:
Time = T: source -> w1 -> ... -> destination
In case the shortest path is not unique, output the fastest one among the shortest paths, which is guaranteed to be unique. In case the fastest path is not unique, output the one that passes through the fewest intersections, which is guaranteed to be unique.
In case the shortest and the fastest paths are identical, print them in one line in the format:
Distance = D; Time = T: source -> u1 -> ... -> destination
Sample Input 1:
10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
3 4 0 3 2
3 9 1 4 1
0 6 0 1 1
7 5 1 2 1
8 5 1 2 1
2 3 0 2 2
2 1 1 1 1
1 3 0 3 1
1 4 0 1 1
9 7 1 3 1
5 1 0 5 2
6 5 1 1 2
3 5
Sample Output 1:
Distance = 6: 3 -> 4 -> 8 -> 5
Time = 3: 3 -> 1 -> 5
Sample Input 2:
7 9
0 4 1 1 1
1 6 1 1 3
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 1 3
3 2 1 1 2
4 5 0 2 2
6 5 1 1 2
3 5
Sample Output 2:
Distance = 3; Time = 4: 3 -> 2 -> 5
题意:
给出一个图,和图中节点之间的关系,求最短路径和最少耗时的路径。(单词:one-way-->单向的)
思路:
我们都知道图论中常用到的算法有:深度优先搜索,广度优先搜索,普利姆算法,克鲁斯卡尔算法,迪杰斯特拉算法,弗洛伊德算法,马踏棋盘算法。其中BFS和DFS是用的比较多的两种算法,理解起来也是相对较容易的,后面的很多算法都是建立在BFS和DFS的基础上。Prim‘s algorithm和Kruskal‘s algorithm是用来求最小生成树(将各个顶点连接起来,使各个边的权值之和最小)。Dijkstra‘s algorithm和Floyd‘s algorithm是用来求最短路径问题的。Dijkstra‘s algorithm是用来求单个顶点到其他顶点的最短路径的,而Floyd‘s algorithm使用来求各个顶点到其他顶点的最短路径的。马踏棋盘算法是使用深搜+贪心来解决问题。
根据本题的题意,我们应该使用Dijkstra‘s algorithm来解决这个问题。在Dijsktra‘s algorithm中有三个重要的数组:
1. visited[]:用来表示该顶点是否被遍历过。
2. path[]: 用来存储该顶点的前驱顶点。
3. dis[]: 用来存储到各个顶点的最短距离。
这三个数组在使用的时候都会动态地更新。初始化的时候应该将visited[]都更新为false;pre[]更新为节点本身;dis[]更新为INF(dis[start] = 0)。根据Dijkstra‘s algorithm的原理,不断地寻找与当前已连通子图距离最近的结点,并将其收纳入已连通的子图,直至将所有的顶点都收纳进来。
1 int minn = inf, u; 2 for (int i = 0; i < n; ++i) { 3 if (visited[i] == false && minn < dis[i]) { 4 minn = dis[i]; 5 u = i; 6 } 7 }
上面这段代码又来寻找寻找与当前已连通子图距离最近的结点。
visited[u] = true; for (int i = 0; i < n; ++i) { if (visited[i] == false && eage[u][i] != inf) { if (dis[u] + eage[u][i] < dis[i]) { dis[i] = dis[u] + eage[u][i]; pre[i] = u; } } }
上面这段代码是用来更新与已连通子图相连的节点到起点的最短距离。
普通的最短路问题用上面的两段代码基本上就解决了,但是本题要求如果最短路径相等则,则求出花费的时间最少的那个。所以当路径相等的时候在更新前驱结点的时候应该注意到这里。最短时间和最短路径的思路基本相等,只不过是用另外一个数组存储罢了。
Code:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int inf = 0x7fffffff; 6 stack<int> shortestPath, leastTimePath; 7 int eage[505][505], consume[505][505]; 8 int path[505], dis[505], times[505]; 9 int visited[505]; 10 int numOfIntersections[505]; 11 12 int main() { 13 int n, m; 14 cin >> n >> m; 15 fill(eage[0], eage[0] + 505 * 505, inf); 16 fill(consume[0], consume[0] + 505 * 505, inf); 17 fill(dis, dis + 505, inf); 18 fill(times, times + 505, inf); 19 fill(visited, visited + 505, 0); 20 fill(numOfIntersections, numOfIntersections + 505, inf); 21 for (int i = 0; i < 505; ++i) path[i] = i; 22 int v1, v2, one_way, len, t; 23 for (int i = 0; i < m; ++i) { 24 cin >> v1 >> v2 >> one_way >> len >> t; 25 eage[v1][v2] = len; 26 consume[v1][v2] = t; 27 if (!one_way) { 28 eage[v2][v1] = len; 29 consume[v2][v1] = t; 30 } 31 } 32 int start, end; 33 cin >> start >> end; 34 dis[start] = 0; 35 times[start] = 0; 36 for (int i = 0; i < n; ++i) { 37 int minn = inf, vertex = -1; 38 for (int j = 0; j < n; ++j) { 39 if (visited[j] == 0 && dis[j] < minn) { 40 minn = dis[j]; 41 vertex = j; 42 } 43 } 44 if (vertex == -1) break; 45 visited[vertex] = 1; 46 for (int j = 0; j < n; ++j) { 47 if (visited[j] == 0 && eage[vertex][j] != inf) { 48 if (dis[vertex] + eage[vertex][j] < dis[j]) { 49 dis[j] = dis[vertex] + eage[vertex][j]; 50 path[j] = vertex; 51 times[j] = times[vertex] + consume[vertex][j]; 52 } else if (dis[vertex] + eage[vertex][j] == dis[j] && 53 times[vertex] + consume[vertex][j] < times[j]) { 54 path[j] = vertex; 55 times[j] = times[vertex] + consume[vertex][j]; 56 } 57 } 58 } 59 } 60 int temp = end; 61 shortestPath.push(temp); 62 while (temp != start) { 63 shortestPath.push(path[temp]); 64 temp = path[temp]; 65 } 66 fill(times, times + 505, inf); 67 fill(visited, visited + 505, 0); 68 times[start] = 0; 69 numOfIntersections[start] = 1; 70 for (int i = 0; i < n; ++i) { 71 int minn = inf, vertex = -1; 72 for (int j = 0; j < n; ++j) { 73 if (visited[j] == 0 && times[j] < minn) { 74 minn = times[j]; 75 vertex = j; 76 } 77 } 78 if (vertex == -1) break; 79 visited[vertex] = 1; 80 for (int j = 0; j < n; ++j) { 81 if (visited[j] == 0 && consume[vertex][j] != inf) { 82 if (times[vertex] + consume[vertex][j] < times[j]) { 83 times[j] = times[vertex] + consume[vertex][j]; 84 numOfIntersections[j] = numOfIntersections[vertex] + 1; 85 path[j] = vertex; 86 } else if (times[vertex] + consume[vertex][j] == times[j] && 87 numOfIntersections[vertex] + 1 < 88 numOfIntersections[j]) { 89 numOfIntersections[j] = numOfIntersections[vertex] + 1; 90 path[j] = vertex; 91 } 92 } 93 } 94 } 95 temp = end; 96 leastTimePath.push(temp); 97 while (temp != start) { 98 leastTimePath.push(path[temp]); 99 temp = path[temp]; 100 } 101 102 if (shortestPath != leastTimePath) { 103 cout << "Distance = " << dis[end] << ": " << shortestPath.top(); 104 shortestPath.pop(); 105 while (!shortestPath.empty()) { 106 cout << " -> " << shortestPath.top(); 107 shortestPath.pop(); 108 } 109 cout << endl; 110 cout << "Time = " << times[end] << ": " << leastTimePath.top(); 111 leastTimePath.pop(); 112 while (!leastTimePath.empty()) { 113 cout << " -> " << leastTimePath.top(); 114 leastTimePath.pop(); 115 } 116 } else { 117 cout << "Distance = " << dis[end] << "; Time = " << times[end] << ": " 118 << leastTimePath.top(); 119 leastTimePath.pop(); 120 while (!leastTimePath.empty()) { 121 cout << " -> " << leastTimePath.top(); 122 leastTimePath.pop(); 123 } 124 } 125 126 return 0; 127 }
参考: https://www.liuchuo.net/archives/2407
以上是关于1111 Online Map的主要内容,如果未能解决你的问题,请参考以下文章
A1111 Online Map (30分)(最短路径Dijkstra+DFS)
PAT (Advanced Level) 1111. Online Map (30)