bzoj2763 [JLOI2011]飞行路线

Description

\(Alice\)\(Bob\) 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在 \(n\) 个城市设有业务,设这些城市分别标记为 \(0\)\(n-1\),一共有 \(m\) 种航线,每种航线连接两个城市,并且航线有一定的价格。 \(Alice\)\(Bob\) 现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么 \(Alice\)\(Bob\) 这次出行最少花费多少?

Input

数据的第一行有三个整数, \(n,m,k\) ,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数, \(s,t\) ,分别表示他们出行的起点城市编号和终点城市编号。 \((0\le s,t<n)\)
接下来有 \(m\) 行,每行三个整数, \(a,b,c\) ,表示存在一种航线,能从城市 \(a\) 到达城市 \(b\) ,或从城市 \(b\) 到达城市 \(a\) ,价格为 \(c\) 。( \(0\le a,b<n,a\)\(b\) 不相等, \(0\le c\le 1000\) )

Output

只有一行,包含一个整数,为最少花费。

Sample Input

5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100

Sample Output

8

HINT

对于 \(100\%\) 的数据, \(2\le n\le 10000,1\le m\le 50000,0\le k\le 10\) .

Solution

分层图最短路裸题,用优先队列去除后效性,可用于套版。

#include<bits/stdc++.h>
using namespace std;

#define N 100001
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define fech(i, x) for (int i = 0; i < x.size(); i++)
#define ll long long

inline int read() {
    int x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); }
    while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag;
}

int n, m, k, S, T;
struct edge { int u, v, w; } eg[N]; int tot;
vector<int> g[N];
int d[N][11];
bool vis[N][11];

struct node {
	int u, d, f;
	bool operator < (const node& b) const { return d > b.d; }
};
priority_queue<node> q;

void bfs() {
	memset(d, 127, sizeof d); d[S][0] = 0;
	q.push(node { S, 0, 0 });
	while(!q.empty()) {
		node x = q.top(); q.pop();
		int u = x.u, dis = x.d, f = x.f;
		if(!(u ^ T)) { cout << dis; exit(0); }
		if(vis[u][f]) continue;
		vis[u][f] = 1;
		fech(i, g[u]) {
			edge e = eg[g[u][i]];
			if(f < k && !vis[e.v][f + 1] && d[e.v][f + 1] > dis) d[e.v][f + 1] = dis, q.push(node{ e.v, dis, f + 1 });
			if(!vis[e.v][f] && d[e.v][f] > dis + e.w) d[e.v][f] = dis + e.w, q.push(node{ e.v, dis + e.w, f });
		}
	}
}

int main() {
	scanf("%d%d%d%d%d", &n, &m, &k, &S, &T);
	while(m--) {
		int u = read(), v = read(), w = read();
		eg[++tot] = edge { u, v, w }; g[u].push_back(tot);
		eg[++tot] = edge { v, u, w }; g[v].push_back(tot);
	}
	bfs();
}
posted @ 2018-02-05 10:12  aziint  阅读(112)  评论(0编辑  收藏  举报
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.