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的主要内容,如果未能解决你的问题,请参考以下文章

PAT_A1111#Online Map

A1111 Online Map (30分)(最短路径Dijkstra+DFS)

PAT (Advanced Level) 1111. Online Map (30)

1111 Online Map(迪杰斯特拉+DFS)

1111 Online Map (30 分)难度: 一般 / 知识点: Dijkstra最短路

PAT-1111 Online Map (30分) 最短路+dfs