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,其实也可以直接迭代生成。

// 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/

欢迎讨论和交流!


原文地址:https://www.cnblogs.com/chouxianyu/p/13692483.html