[JLOI2011]飞行路线 分层最短路 + Dijkstra ACM-ICPC 2018 南京赛区网络预赛 L

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

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

输入输出格式
输入格式:
数据的第一行有三个整数,n,m,kn,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,ts,t,分别表示他们出行的起点城市编号和终点城市编号。
接下来有m行,每行三个整数,a,b,ca,b,c,表示存在一种航线,能从城市aa到达城市bb,或从城市bb到达城市aa,价格为cc。

输出格式:
只有一行,包含一个整数,为最少花费。

输入输出样例
输入样例#1:
5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
输出样例#1:
8
说明
对于30%的数据,2 \le n \le 50,1 \le m \le 300,k=02≤n≤50,1≤m≤300,k=0;
对于50%的数据,2 \le n \le 600,1 \le m \le 6000,0 \le k \le 12≤n≤600,1≤m≤6000,0≤k≤1;
对于100%的数据,2 \le n \le 10000,1 \le m \le 50000,0 \le k \le 102≤n≤10000,1≤m≤50000,0≤k≤10,0 \le s,t<n,0 \le a,b<n,a\neq b,0 \le c \le 10000≤s,t<n,0≤a,b<n,a≠b,0≤c≤1000

评测方式 云端评测
标签 各省省选2011吉林
难度 省选/NOI-
时空限制 1000ms / 128MB

与普通的最短路差不多;
建立一个分层即可;
各位大爷看代码就懂了 orz
和这次的 ACM-ICPC 2018 南京赛区网络预赛 L 相同的思路

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define sq(x) (x)*(x)
#define eps 1e-6
const int N = 2500005;
typedef pair<int, int> pii;


inline int read()
{
	int x = 0, k = 1; char c = getchar();
	while (c < '0' || c > '9') { if (c == '-')k = -1; c = getchar(); }
	while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	return x * k;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}

int s, t, n, m, k;
int vis[maxn][30];
vector<pii>G[maxn];
int d[maxn][20];


struct node {
	int id, lev, dis;
	node(){}
	node(int id,int lev,int dis):id(id),lev(lev),dis(dis){}

	bool operator <(const node&rhs)const {
		return dis > rhs.dis;
	}
};


priority_queue<node>pq;

int main()
{
	ios::sync_with_stdio(false);
	int a, b, c;
	cin >> n >> m >> k;
	for (int i = 0; i < n; i++)G[i].clear();
	ms(vis); cin >> s >> t;
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> c;
		G[a].push_back(make_pair(b, c)); G[b].push_back(make_pair(a, c));
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j <= k; j++)d[i][j] = inf;
	}
	d[s][0] = 0;
	pq.push(node(s, 0, 0));
	while (!pq.empty()) {
		node tp = pq.top(); pq.pop();
		int x = tp.id; int lv = tp.lev;
		if (vis[x][lv])continue;
		else {
			vis[x][lv] = 1;
			vector<pii>::iterator it;
			for (it = G[x].begin(); it != G[x].end(); it++) {
				int y = (*it).first; int w = (*it).second;
				if (d[x][lv] + w < d[y][lv]) {
					d[y][lv] = d[x][lv] + w; pq.push(node(y, lv, d[y][lv]));
				}

				if (lv < k) {
					if (d[x][lv] < d[y][lv + 1]) {
						d[y][lv + 1] = d[x][lv];
						pq.push(node(y, lv + 1, d[y][lv + 1]));
					}
				}
			}
		}
	}
	int res = d[t][0];
	for (int i = 0; i <= k; i++)res = min(res, d[t][i]);
	cout << res << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值