飞行路线(分层图)

飞行路线(分层图)

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;
}
posted @ 2022-07-22 13:29  hzy0227  阅读(144)  评论(0编辑  收藏  举报