1111 Online Map (30 分)
 

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指的是当前的两个节点v1、v2是否为单向路径。

思路:两次Dijkstra即可,采用邻接表+堆优化(使用C++的queue容器,priority_queue本质上就是一个堆,不嫌麻烦的也可以手写堆的操作)的Dijkstra算法,题目里面对每条路径都有两个优先级的要求,所以需要在struct里面设置变量的优先级。

核心就是Dijkstra算法,一下子看不懂的话可以将教材上的DIjkstra算法人肉实现几遍然后仔细阅读源码。先学习最原始的使用邻接矩阵的未优化版本,然后改用邻接表并加入堆的优化,这里不得不赞美一下强大的stl,如果没有priority_queue的话还需要手撸一个堆,代码越长越容易出bug,毕竟人类是有极限的啊(我不做人了,JOJO!)。

 #include <iostream>
#include <unordered_map>
#include <vector>
#include <queue>
#define INFI 10000
#define MaxVNum 500
using namespace std;
struct ENode {
int length = INFI, time = INFI;
} E[MaxVNum][MaxVNum];//边
struct distNode {
int u, dist = INFI, time = INFI;
friend bool operator < (const distNode &a, const distNode &b) {
return a.dist != b.dist ? a.dist > b.dist : a.time > a.time;
}
};
struct timeNode {
int u, time = INFI, num = INFI;
friend bool operator < (const timeNode &a, const timeNode &b) {
return a.time != b.time ? a.time > b.time : a.num > b.num;
}
};
vector <int> V[MaxVNum];//顶点
int sPath[MaxVNum], fPath[MaxVNum];//分别记录最短路径和最快路径
int DijkstraDis(int sour, int des, int N);
int DijkstraTime(int sour, int des, int N);
void printPath(vector <int> &v, int &size);//将逆序路径顺序输出
int main()
{
int N, M, sour, des;
scanf("%d%d", &N, &M);
for (int i = ; i < M; i++) {
int v1, v2, flag, len, time;
scanf("%d%d%d%d%d", &v1, &v2, &flag, &len, &time);
V[v1].push_back(v2);
E[v1][v2].length = len;
E[v1][v2].time = time;
if (!flag) {
V[v2].push_back(v1);
E[v2][v1].length = len;
E[v2][v1].time = time;
}
}
scanf("%d%d", &sour, &des);
int dis = DijkstraDis(sour, des, N);
int time = DijkstraTime(sour, des, N);
vector <int> ans1, ans2;
for (int x = des; x != -; x = sPath[x])
ans1.push_back(x);
for (int x = des; x != -; x = fPath[x])
ans2.push_back(x);
int size1 = ans1.size(), size2 = ans2.size();
bool flag = true;
if (size1 == size2) {
for (int i = ; i < size1; i++) {
if (ans1[i] != ans2[i]) {
flag = false;
break;
}
}
}
if (size1 == size2 && flag) {
printf("Distance = %d; Time = %d:", dis, time);
printPath(ans1, size1);
}
else {
printf("Distance = %d:", dis);
printPath(ans1, size1);
printf("Time = %d:", time);
printPath(ans2, size2);
}
return ;
}
void printPath(vector <int> &v, int &size) {
for (int i = size - ; i >= ; i--) {
printf(" %d", v[i]);
if (i > ) {
printf(" ->");
}
}
printf("\n");
}
int DijkstraTime(int sour, int des, int N) {
vector <bool> collected(N, false);
vector <int> time(N,INFI), num(N,INFI);
priority_queue <timeNode> Q;
int u, w;
for (u = ; u < N; u++)
fPath[u] = -;
timeNode vertex;
vertex.u = sour;
vertex.time = time[sour] = ;
vertex.num = num[sour] = ;
Q.push(vertex);
while (!Q.empty()) {
vertex = Q.top();
Q.pop();
u = vertex.u;
collected[u] = true;
for (int i = ; i < V[u].size(); i++) {
w = V[u][i];
if (!collected[w]) {
if (time[u] + E[u][w].time < time[w] || (time[u] + E[u][w].time == time[w] && num[u] + < num[w])) {
time[w] = time[u] + E[u][w].time;
num[w] = num[u] + ;
fPath[w] = u;
vertex.u = w;
vertex.time = time[w];
vertex.num = num[w];
Q.push(vertex);
}
}
}
}
return time[des];
}
int DijkstraDis(int sour, int des, int N) {
vector <bool> collected(N, false);
vector <int> dist(N,INFI), time(N,INFI);
priority_queue <distNode> Q;
distNode vertex;
int u, w;
for (w = ; w < N; w++)
sPath[w] = -;
vertex.u = sour;
vertex.dist = dist[sour] = ;
vertex.time = time[sour] = ;
Q.push(vertex);
while (!Q.empty()) {
vertex = Q.top();
Q.pop();
u = vertex.u;
collected[u] = true;
for (int i = ; i < V[u].size(); i++) {
w = V[u][i];
if (!collected[w]) {
if (dist[u] + E[u][w].length < dist[w] || (dist[u] + E[u][w].length == dist[w] && time[u] + E[u][w].time < time[w])) {
dist[w] = dist[u] + E[u][w].length;
time[w] = dist[u] + E[u][w].time;
sPath[w] = u;
vertex.u = w;
vertex.dist = dist[w];
vertex.time = time[w];
Q.push(vertex);
}
}
}
}
return dist[des];
}

PAT甲级——1111 Online Map (单源最短路经的Dijkstra算法、priority_queue的使用)的更多相关文章

  1. PAT甲级1111. Online Map

    PAT甲级1111. Online Map 题意: 输入我们当前的位置和目的地,一个在线地图可以推荐几条路径.现在你的工作是向你的用户推荐两条路径:一条是最短的,另一条是最快的.确保任何请求存在路径. ...

  2. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  3. 单源最短路径问题之dijkstra算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 算法的原理 以源点开始,以源点相连的顶点作为向外延伸的顶点,在所有这些向外延伸的顶 ...

  4. 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法

    Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...

  5. 单源最短路径—Bellman-Ford和Dijkstra算法

    Bellman-Ford算法:通过对边进行松弛操作来渐近地降低从源结点s到每个结点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重相同时为止.该算法主要是基于下面的定理: 设G=(V,E) ...

  6. 单源最短路:Dijkstra算法 及 关于负权的讨论

    描述: 对于图(有向无向都适用),求某一点到其他任一点的最短路径(不能有负权边). 操作: 1. 初始化: 一个节点大小的数组dist[n] 源点的距离初始化为0,与源点直接相连的初始化为其权重,其他 ...

  7. PAT甲级1131. Subway Map

    PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ...

  8. spfa 单源最短路究极算法

    学习博客链接:SPFA 求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm.     SPFA算法是西南交通大学段凡丁于1994年发表的.    从名字我 ...

  9. 单源最短路径问题1 (Bellman-Ford算法)

    /*单源最短路径问题1 (Bellman-Ford算法)样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9] */ ...

随机推荐

  1. java2 -宏观了解

    java2 -宏观了解 2016-01-24 16:17 308人阅读 评论(38) 收藏 举报  分类: JAVA(2)  版权声明:本文为博主原创文章,未经博主允许不得转载. Java2平台包括: ...

  2. XML文件的特点

    1.这个东西的规则比较简单,并且人眼看起来也比较容易理解,结构上也比较好操作,并且并无与任何编程语言绑定. 所以,很多编程语言就都为XML这个东西编写了读写XML的库,所以XML看起来所谓的通用,其实 ...

  3. CSS3实现3D木块旋转动画

    CSS3实现3D木块旋转动画,css3特效,旋转动画,3D,立体效果,CSS3实现3D木块旋转动画是一款迷人的HTML5+CSS3实现的3D旋转动画. 代码下载:http://www.huiyi8.c ...

  4. BZOJ 4582 [Usaco2016 Open]Diamond Collector:贪心【相差不超过k】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4582 题意: 给你n个数. 让你将其中的一些数放入两个不同的集合中,并保证同一集合内两两元 ...

  5. Composer基础应用1

    先唠叨唠叨一些琐碎的事.本人最早从事.Net开发,后来处于好奇慢慢转到了php,因为.net从一早就使用了命名空间(反正从我使用就存在这玩意了),所以在转php时很自然的就使用了命名空间,但是在使用过 ...

  6. IOC/DI控制反转与依赖注入

    IOC/DI控制反转与依赖注入 IOC和DI表现的效果的是一样的只不过对于作用的对象不同,有了不一样的名字. 先用一个现实的例子来说明IOC/DI表现出来的效果.

  7. android自定义控件(四) View中的方法

    onFinishInflate() 当View中所有的子控件 均被映射成xml后触发 onMeasure(int, int) 确定所有子元素的大小 onLayout(boolean, int, int ...

  8. zabbix告警邮件美化

    为了更好的用户体验,我们需要尽量美化我们的输出内容,尽量做到整齐划一,让人看了会有很舒服的感觉, 这个好像和苹果的产品一样,给人一种美感让人感觉非常享受. 一般我们的zabbix告警邮件就是纯文字,建 ...

  9. T(n) = 25T(n/5)+n^2的时间复杂度

    对于T(n) = a*T(n/b)+c*n^k;T(1) = c 这样的递归关系,有这样的结论: if (a > b^k)   T(n) = O(n^(logb(a)));logb(a)b为底a ...

  10. CDN网络原理

    1.用户向浏览器输入www.web.com这个域名,浏览器第一次发现本地没有dns缓存,则向网站的DNS服务器请求: 2.网站的DNS域名解析器设置了CNAME,指向了www.web.51cdn.co ...