【PAT甲级】1030 Travel Plan

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:PAT题解集合
📝原题地址:题目详情 - 1030 Travel Plan (pintia.cn)
🔑中文翻译:旅行计划
📣专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

1030 Travel Plan

A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:

0 2 3 3 40
题意

给定一个旅游地图,每个城市之间用高速公路双向连通。

第一行输入分别给定城市数量 N N N 、高速公路数量 M M M 、起始城市 S S S 和终点城市 T T T

第二行给定每个城市之间的道路信息,格式如下:

城市1的编号 城市2的编号 公路长度 花费

城市编号范围是 0 ∽ N − 1 0\backsim N-1 0N1

需要我们找到在最短路径下花费最少的路径,并输出最短路径中每个城市的编号、该最短路径的长度已经最小花费,保证最小花费的路径是唯一的。

思路

这道题我们可以用迪杰斯特拉算法来求最短路,这个算法大致的思想就是每次都找到图中最短的那条路径,然后更新于它相邻边的路进值,具体的讲解可以参考我之前的博客,那里有更详细的图解。

这道题可以在算法计算的过程中顺便去更新最小花费,并记录最短路径。由于题目保证最小花费的路径是唯一的,所以我们可以用一个 pre 数组来记录每个结点是从哪个结点更新过来的,遇到路径最小的或花费最小的就覆盖该结点的值,最后只需要从终点往前找,就能找到最短路径了。

代码
#include<bits/stdc++.h>
using namespace std;

const int N = 510;
int n, m, S, T;
int d[N][N], c[N][N], w[N];
int dist[N], cost[N], pre[N];
bool st[N];

void dijkstra()
{
    //初始化
    memset(dist, 0x3f, sizeof dist);
    dist[S] = 0;

    for (int i = 0; i < n; i++)
    {
        int t = -1;
        for (int j = 0; j < n; j++)    //找到一条最短路径
            if (!st[j] && (t == -1 || dist[j] < dist[t]))
                t = j;
        st[t] = true;

        for (int j = 0; j < n; j++)    //更新信息
        {
            if (dist[j] > dist[t] + d[t][j])
            {
                //如果找到更短的路径,将所有信息都更新
                dist[j] = dist[t] + d[t][j];
                cost[j] = cost[t] + c[t][j];
                pre[j] = t;
            }
            else if (dist[j] == dist[t] + d[t][j] && cost[j] > cost[t] + c[t][j])
            {
                //如果找到一条相同的最短路,只需更新花费更小的路径
                cost[j] = cost[t] + c[t][j];
                pre[j] = t;
            }
        }
    }
}

int main()
{
    cin >> n >> m >> S >> T;

    memset(d, 0x3f, sizeof d);
    memset(c, 0x3f, sizeof c);

    //输入公路信息
    while (m--)
    {
        int a, b, x, y;
        cin >> a >> b >> x >> y;
        d[a][b] = d[b][a] = min(d[a][b], x);
        c[a][b] = c[b][a] = min(c[a][b], y);
    }

    dijkstra(); //迪杰斯特拉算法

    //读取最短路径信息
    vector<int> path;
    for (int i = T; i != S; i = pre[i])  path.push_back(i);

    cout << S;
    for (int i = path.size() - 1; i >= 0; i--)   cout << " " << path[i];
    cout << " " << dist[T] << " " << cost[T] << endl;

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值