PAT甲级1030Travel Plan

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805464397627392

题解

题目要求

  • 输入
    • N:正整数,不超过500,结点的数量,索引为[0,N-1]
    • M:正整数,边的数量
    • S:起点索引
    • D:终点索引
    • M条边
  • 输出
    • 最短路径经过的结点
    • 总距离
    • 总成本

解题思路

该题在普通最短路径题目基础上补充了2点

我是先做了PAT甲级1018Public Bike Management,这两题很相似,1018更难,这题更简单。

  1. 输出最短路径经过的结点

    因为最终的最短路径只有一条,所以保存最短路径中每个结点的前一个结点,最终从D往回遍历即可

  2. 优先考虑距离,再考虑成本

    通过if语句实现

代码

最后生成path时我是递归存入vector,其实也可以直接迭代生成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Problem: PAT Advanced 1030
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805464397627392
// Tags: 最短路 图 dijkstra 单源最短路 BFS

#include <iostream>
#include <vector>
using namespace std;

const int MAXN = 500;
const int INF = 9999999;
int n, m, s, d;
bool visited[MAXN];
int minDis[MAXN];
int minCost[MAXN];
int dis[MAXN][MAXN];
int cost[MAXN][MAXN];
int pre[MAXN];
vector<int> path;

void getPath(int v){
path.push_back(v);
if (v != s){
getPath(pre[v]);
}
}

int main()
{
fill(minDis, minDis + MAXN, INF);
fill(minCost, minCost + MAXN, INF);
fill(dis[0], dis[0] + MAXN * MAXN, INF);
fill(cost[0], cost[0] + MAXN * MAXN, INF);

scanf("%d %d %d %d", &n, &m, &s, &d);
int a, b;
for (int i = 0; i < m; i++){
scanf("%d %d", &a, &b);
scanf("%d %d", &dis[a][b], &cost[a][b]);
dis[b][a] = dis[a][b];
cost[b][a] = cost[a][b];
}

minDis[s] = 0;
minCost[s] = 0;
for (int i = 0; i < n; i++){
int u = -1, minD = INF;
for (int j = 0; j < n; j++){
if (!visited[j] && minDis[j] < minD){
minD = minDis[j];
u = j;
}
}
if (u == -1) break;
visited[u] = true;

for (int v = 0; v < n; v++){
if (!visited[v] && dis[u][v] != INF){
if (minDis[u] + dis[u][v] < minDis[v]){
minDis[v] = minDis[u] + dis[u][v];
minCost[v] = minCost[u] + cost[u][v];
pre[v] = u;
}
else if (minDis[u] + dis[u][v] == minDis[v] && minCost[u] + cost[u][v] < minCost[v]){
minCost[v] = minCost[u] + cost[u][v];
pre[v] = u;
}
}
}

}

getPath(d);

for (auto iter = path.rbegin(); iter != path.rend(); iter++)
printf("%d ", *iter);
printf("%d %d", minDis[d], minCost[d]);
return 0;
}

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!