Description
Alice
和
Bob
现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在
n
个城市设有业务,设这些城市分别标记为
Input
数据的第一行有三个整数,
n,m,k
,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,
s,t
,分别表示他们出行的起点城市编号和终点城市编号。
(0≤s,t<n)
接下来有
m
行,每行三个整数,
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≤n≤10000,1≤m≤50000,0≤k≤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();
}