看板娘加载较慢请耐心等待qwq~~~

Luogu4568[JLOI2011][分层图] 飞行路线

Luogu4568[JLOI2011][分层图] 飞行路线

题目描述

Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在 \(n\) 个城市设有业务,设这些城市分别标记为 \(0\)\(n-1\),一共有 \(m\) 种航线,每种航线连接两个城市,并且航线有一定的价格。

Alice 和 Bob 现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多 \(k\) 种航线上搭乘飞机。那么 Alice 和 Bob 这次出行最少花费多少?

sov

分层图板子。考虑每一次使用免费操作的时候,就进入到下一层。也就是说开数组的时候,多开一维记录使用了几次免费转移操作,在spfa/dij的时候,记录点和第几层。

code

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e4 + 10;
const int MAXM = 5e4 + 10;
int ver[MAXM << 1], nxt[MAXM << 1], edge[MAXM << 1], head[MAXN], tot;
inline void add(const int &x, const int &y, const int &z)
{
	ver[++tot] = y;
	nxt[tot] = head[x];
	edge[tot] = z;
	head[x] = tot;
}
int d[MAXN][11];
bool v[MAXN][11];
int n, m, k, s, t;
void dij()
{
	struct node
	{
		int x, k, d;
		bool operator<(const node b)const
		{
			return d > b.d;
		}
	};
	priority_queue<node> q;
	memset(d, 0x3f, sizeof(d));
	q.push({s, 0, 0});
	d[s][0] = 0;
	while(q.size())
	{
		node tmp = q.top();
		q.pop();
		if(v[tmp.x][tmp.k])
			continue;
		v[tmp.x][tmp.k] = 1;
		for(int i = head[tmp.x]; i; i = nxt[i])
		{
			int y = ver[i], z = edge[i];
			if(d[y][tmp.k] > d[tmp.x][tmp.k] + z)
			{
				d[y][tmp.k] = d[tmp.x][tmp.k] + z;
				q.push({y, tmp.k, d[y][tmp.k]});
			}
			if(tmp.k + 1 <= k && d[y][tmp.k + 1] > d[tmp.x][tmp.k])
			{
				d[y][tmp.k + 1] = d[tmp.x][tmp.k];
				q.push({y, tmp.k + 1, d[y][tmp.k + 1]});
			}
		}
	}
}
void spfa()
{
	queue<pair<int,int> > q;
	q.push({s, 0});
	memset(d, 0x3f, sizeof(d));
	d[s][0] = 0;
	v[s][0] = 1;
	while(q.size())
	{
		int x = q.front().first;
		int t = q.front().second;
		q.pop();
		v[x][t] = 0;
		for(int i = head[x]; i; i = nxt[i])
		{
			int y = ver[i], z = edge[i];
			if(d[y][t] > d[x][t] + z)
			{
				d[y][t] = d[x][t] + z;
				if(!v[y][t])
					q.push({y, t});
			}
			if(t + 1 <= k && d[y][t + 1] > d[x][t])
			{
				d[y][t + 1] = d[x][t];
				if(!v[y][t + 1])
					q.push({y, t + 1});
			}
		}
	}
}
int main()
{
	cin >> n >> m >> k >> s >> t;
	for(int i = 1, x, y, z; i <= m; ++i)
	{
		cin >> x >> y >> z;
		add(x, y, z);
		add(y, x, z);
	}
	dij();
	int ans = INT_MAX;
	for(int i = 0; i <= k; ++i)
	{
		ans = min(ans, d[t][i]);
	}
	cout << ans << endl;
}
posted @ 2022-07-24 17:53  椎名·六花  阅读(19)  评论(0编辑  收藏  举报