【PAT A-1030】Travel Plan

【PAT A-1030】Travel Plan

题意概述

给出城市之间的距离以及城市之间每条公路的成本。你需要找到出发城市和目的地之间的最短路径。如果这样的最短路径不是唯一的,则应该以最低的成本输出该路径,这保证是唯一的。

输入输出格式

输入第一行包含 4 个正整数 N,M,S 和 D,分别表示城市数(城市从 0 到 N-1 编号)、公路数量、 起始城市和目标城市。接下来 M 行,每行以City1 City2 Distance Cost格式来描述一条公路。

在一行中打印沿起点到目的地的最短路径的城市,然后是路径的总距离和总成本。数字必须用空格分隔,并且输出末尾不得有多余的空格。

数据规模

N < = 500 N<=500 N<=500

算法设计

题目比较简单,使用 Dijkstra 算法求出符合要求的最短路径,利用 DFS 输出该路径即可,具体实现可见代码

C++代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
const gg MAX = 505;
using agg3 = array<gg, 3>;
struct Edge {
    gg to, dis, cost;
    Edge(gg t, gg d, gg c) : to(t), dis(d), cost(c) {}
};
vector<vector<Edge>> graph(MAX);
vector<gg> dis(MAX, INT_MAX), cost(MAX, INT_MAX), past(MAX, -1);
void Dijkstra(gg s) {
    priority_queue<agg3, vector<agg3>, greater<agg3>> pq;
    dis[s] = 0;
    cost[s] = 0;
    pq.push({0, 0, s});
    while (!pq.empty()) {
        auto p = pq.top();
        pq.pop();
        if (dis[p[2]] != p[0] or cost[p[2]] != p[1]) {
            continue;
        }
        for (auto& e : graph[p[2]]) {
            if (tie(dis[e.to], cost[e.to]) >
                make_tuple(p[0] + e.dis, p[1] + e.cost)) {
                dis[e.to] = p[0] + e.dis;
                cost[e.to] = p[1] + e.cost;
                past[e.to] = p[2];
                pq.push({dis[e.to], cost[e.to], e.to});
            }
        }
    }
}
void dfs(gg v) {
    if (past[v] == -1) {
        cout << v << " ";
        return;
    }
    dfs(past[v]);
    cout << v << " ";
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    gg ni, mi, si, di;
    cin >> ni >> mi >> si >> di;
    for (gg i = 0; i < mi; ++i) {
        gg a, b, c, d;
        cin >> a >> b >> c >> d;
        graph[a].push_back(Edge(b, c, d));
        graph[b].push_back(Edge(a, c, d));
    }
    Dijkstra(si);
    dfs(di);
    cout << dis[di] << " " << cost[di];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我真的不是cjc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值