Files
cpp-courseware/2.Course/2.深入浅出程序设计竞赛(提高篇)/最短路/C++源码/03_flights.cpp
T

51 lines
1.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// P4568 / 教材例 10-2:隐式分层图,最多 k 次免费。
// n m k;s t;m 行 u v w。城市从 0 编号,无向非负边。
// 课堂扩展约定:如果没有路线,输出 -1;原题未指定此情况的输出。
#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
#include <functional>
#include <algorithm>
using namespace std;
using ll = long long;
using State = tuple<ll, int, int>;
struct Edge { int to; ll w; };
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
int n, m, k, s, t;
if (!(cin >> n >> m >> k >> s >> t)) return 0;
vector<vector<Edge>> g(n);
for (int i = 0; i < m; ++i) {
int u, v; ll w; cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
const ll INF = (1LL << 60);
vector<vector<ll>> dis(k + 1, vector<ll>(n, INF));
priority_queue<State, vector<State>, greater<State>> q;
dis[0][s] = 0;
q.push({0, s, 0});
while (!q.empty()) {
State cur = q.top(); q.pop();
ll d = get<0>(cur);
int u = get<1>(cur), j = get<2>(cur);
if (d != dis[j][u]) continue;
for (const auto &e : g[u]) {
int v = e.to;
ll nd = d + e.w;
if (nd < dis[j][v]) {
dis[j][v] = nd;
q.push({nd, v, j});
}
if (j < k && d < dis[j + 1][v]) {
dis[j + 1][v] = d;
q.push({d, v, j + 1});
}
}
}
ll ans = INF;
for (int j = 0; j <= k; ++j) ans = min(ans, dis[j][t]);
cout << (ans == INF ? -1 : ans) << '\n';
}