飞行路线(分层图)
飞行路线(分层图)
JLOI2011] 飞行路线 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
最多有 k 条航线可以免费走,就让建 k + 1 层图,\(dist[i][j]\) 表示从第 0 层起点经过 j 条免费航线到达第 i 结点,答案就是 \(min(dist[t][j])\)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
#define endl "\n"
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e4 + 10;
const int INF = 0x3f3f3f3f;
int n, m, k, s, t;
int dist[N][12];
bool st[N][12];
struct Node
{
int u, d, cnt;
bool operator<(const Node &x) const
{
return d > x.d;
}
};
struct Edge
{
int v, w;
};
vector<vector<Edge> > G(N);
void add(int u, int v, int w)
{
G[u].push_back({v, w});
}
void dijkstra(int s)
{
priority_queue<Node> heap;
memset(dist, 0x3f, sizeof dist);
dist[s][0] = 0;
heap.push({s, dist[s][0], 0});
while(!heap.empty())
{
int u = heap.top().u, now_cnt = heap.top().cnt;
heap.pop();
if (st[u][now_cnt])
continue;
st[u][now_cnt] = true;
for (auto [v, w] : G[u])
{
if (now_cnt < k && dist[v][now_cnt+1] > dist[u][now_cnt])
{
dist[v][now_cnt+1] = dist[u][now_cnt];
heap.push({v, dist[v][now_cnt+1], now_cnt+1});
}
if (dist[v][now_cnt] > dist[u][now_cnt] + w)
{
dist[v][now_cnt] = dist[u][now_cnt] + w;
heap.push({v, dist[v][now_cnt], now_cnt});
}
}
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m >> k >> s >> t;
while(m--)
{
int u, v, w;
cin >> u >> v >> w;
add(u, v, w), add(v, u, w);
}
dijkstra(s);
int ans = INF;
for (int i = 0; i <= k; i++)
ans = min(ans, dist[t][i]);
cout << ans << endl;
return 0;
}