博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PAT甲级 1111 - Online Map(最短路)
阅读量:5140 次
发布时间:2019-06-13

本文共 4904 字,大约阅读时间需要 16 分钟。

PAT甲级1111

题目链接

【题意】

输入当前的位置和目的地,在线地图可以推荐几条路径。现在你的任务是向用户推荐两条路径:一条最短,另一条最快,输入确保有解。

【输入格式】

单组输入,第一行分别给出两个正整数N(2 <= N <= 500)和M,分别是地图上的结点总数和街道的数量。然后按照M行,每一行都按照以下格式描述一条街道:
起点 终点 单程 长度 时间
其中起点和终点是街道两端的结点编号(从0到N-1)如果街道从起点到终点为单向,则单程值为1,否则为0。长度是街道的长度,时间是通过街道所需的时间。
最后给出一对源和目的地。

【输出格式】

首先以最短距离距离D打印从源到目的地的最短路径,格式为:
Distance = D: source -> v1 -> … -> destination
然后在下一行打印总时间为T的最快路径,格式为:
Time = T: source -> w1 -> … -> destination
在最短路径不唯一的情况下,输出最短路径中最快的路径,这是保证唯一的。如果最快的路径不是唯一的,则输出通过最少路口的路段,这也是保证唯一的。
如果最短路径和最快路径相同,则按以下格式将它们打印在一行中,格式为:
Distance = D; Time = T: source -> u1 -> … -> destination

【思路】

图论中的最短路径问题,分别把距离和时间看成图中边的权值,然后用Dijkstra算法求源点到其它各点的最短路径,同时记录每个点的前驱点。因为根据题中的描述,不论是距离最短的最短路径还是时间最短的最短路径,都不一定是唯一的,所以都需要再额外增加一个限制条件。对于距离最短路径来说,用数组d对距离做松弛操作,如果最短路相同,那么再用一个数组t对时间做松弛操作,即在最短路相同的前提下进一步求最短时间。同理,对于时间最短路径来说也是一样,不过这一次是用数组d对时间做松弛操作,用数组t对到达每个结点的最短路所经过结点的个数做松弛操作,即在时间最短的前提下保证经过的结点数最少。

#include
using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 550;struct Edge { int from, to, dist, other; Edge(int f, int t, int d, int o) :from(f), to(t), dist(d), other(o) {}};struct HeapNode { int d, u; HeapNode(int dd, int uu) :d(dd), u(uu) {} bool operator<(const HeapNode& rhs)const { return d > rhs.d; }};struct Dijkstra { int n, m; vector
edges; vector
g[maxn]; vector
path; bool done[maxn]; int d[maxn]; int t[maxn]; int p[maxn]; void init(int n) { path.clear(); this->n = n; for (int i = 0; i < n; ++i) g[i].clear(); edges.clear(); } void add(int from, int to, int dist, int other) { edges.push_back(Edge(from, to, dist, other)); m = edges.size(); g[from].push_back(m - 1); } void dijkstra_Distance(int s) {
//计算最短距离 priority_queue
que; for (int i = 0; i < n; ++i) { d[i] = inf; t[i] = inf; } d[s] = 0; t[s] = 0; memset(done, 0, sizeof(done)); que.push(HeapNode(0, s)); while (!que.empty()) { HeapNode x = que.top(); que.pop(); int u = x.u; if (done[u]) continue; done[u] = true; for (int i = 0; i < g[u].size(); ++i) { Edge& e = edges[g[u][i]]; if (d[e.to] > d[u] + e.dist) { d[e.to] = d[u] + e.dist; t[e.to] = t[u] + e.other; p[e.to] = g[u][i]; que.push(HeapNode(d[e.to], e.to)); } else if (d[e.to] == d[u] + e.dist && t[e.to] > t[u] + e.other) { t[e.to] = t[u] + e.other; p[e.to] = g[u][i]; } } } } void dijkstra_Time(int s) {
//计算最短时间 priority_queue
que; for (int i = 0; i < n; ++i) { d[i] = inf; t[i] = inf; } d[s] = 0; t[s] = 0; memset(done, 0, sizeof(done)); que.push(HeapNode(0, s)); while (!que.empty()) { HeapNode x = que.top(); que.pop(); int u = x.u; if (done[u]) continue; done[u] = true; for (int i = 0; i < g[u].size(); ++i) { Edge& e = edges[g[u][i]]; if (d[e.to] > d[u] + e.dist) { d[e.to] = d[u] + e.dist; t[e.to] = t[u] + 1; p[e.to] = g[u][i]; que.push(HeapNode(d[e.to], e.to)); } else if (d[e.to] == d[u] + e.dist && t[e.to] > t[u] + 1) { t[e.to] = t[u] + 1; p[e.to] = g[u][i]; } } } } void print(int x) { //递归记录以x为终点的最短路径 if (d[x] == 0) { path.push_back(x); return; } Edge& e = edges[p[x]]; print(e.from); path.push_back(x); }};int n, m;Dijkstra Distance, Time;int main() { scanf("%d%d", &n, &m); Distance.init(n); Time.init(n); for (int i = 0; i < m; ++i) { int from, to, oneway, length, time; scanf("%d%d%d%d%d", &from, &to, &oneway, &length, &time); if (oneway == 1) { Distance.add(from, to, length, time); Time.add(from, to, time, length); } else { Distance.add(from, to, length, time); Distance.add(to, from, length, time); Time.add(from, to, time, length); Time.add(to, from, time, length); } } int s, t; scanf("%d%d", &s, &t); Distance.dijkstra_Distance(s); Time.dijkstra_Time(s); Distance.print(t); Time.print(t); bool same = true; if (Distance.path.size() != Time.path.size()) same = false; else { for (int i = 0; i < Distance.path.size(); ++i) { if (Distance.path[i] != Time.path[i]) { same = false; break; } } } if (same) { printf("Distance = %d; Time = %d: ", Distance.d[t], Time.d[t]); printf("%d", Distance.path[0]); for (int i = 1; i < Distance.path.size(); ++i) { printf(" -> %d", Distance.path[i]); } } else { printf("Distance = %d: ", Distance.d[t]); printf("%d", Distance.path[0]); for (int i = 1; i < Distance.path.size(); ++i) { printf(" -> %d", Distance.path[i]); } printf("\nTime = %d: ", Time.d[t]); printf("%d", Time.path[0]); for (int i = 1; i < Time.path.size(); ++i) { printf(" -> %d", Time.path[i]); } printf("\n"); } return 0;}

转载于:https://www.cnblogs.com/wafish/p/10465343.html

你可能感兴趣的文章
利用IP地址查询接口来查询IP归属地
查看>>
构造者模式
查看>>
Hbuild在线云ios打包失败,提示BuildConfigure Failed 31013 App Store 图标 未找到 解决方法...
查看>>
找到树中指定id的所有父节点
查看>>
jQuery on(),live(),trigger()
查看>>
【架构】Linux的架构(architecture)
查看>>
ASM 图解
查看>>
Date Picker控件:
查看>>
你的第一个Django程序
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>