洛谷P4568 分层图最短路
题意:n个点,m条双向边,给出起点终点,最多有k条边可以免费通过,求起点到终点的最短路
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
const int N = 10010;
const int M = 100010;
const int INF = 0x3f3f3f3f;
int n, m , t, l = 0;
int ss, st;
int last[N], pre[M], other[M], len[M];
int dis[N][15];
bool vis[N][15] = {false};
struct rec{
int x, dis, use;
bool operator < (const rec &a) const {
return (a.dis < dis);
}
};
inline void read(int &x) {
x = 0; bool flag = false; char ch;
while (ch = getchar(), ch < '!');
if (ch == '-') flag = true, ch = getchar();
while (x = x * 10 + ch - '0', ch = getchar(), ch > '!');
if (flag) x = -x;
}
void connect(int x, int y, int z) {
l++;
pre[l] = last[x];
last[x] = l;
other[l] = y;
len[l] = z;
}
void dijkstra() {
priority_queue<rec> que;
memset(dis, 0x3f, sizeof(dis));
//for (int i = 0; i <= t; i++) dis[ss][i] = 0;
dis[ss][0] = 0;
que.push(rec{ss, 0, 0});
//
while (!que.empty()) {
rec cur = que.top();
que.pop();
if (vis[cur.x][cur.use]) continue;
vis[cur.x][cur.use] = true;
//
int p, q;
q = last[cur.x];
while (q != 0) {
p = other[q];
if (dis[p][cur.use] > cur.dis + len[q]) {
dis[p][cur.use] = cur.dis + len[q];
que.push(rec{p, dis[p][cur.use], cur.use});
}
if ((cur.use < t) && (dis[p][cur.use + 1] > cur.dis)) {
dis[p][cur.use + 1] = cur.dis;
que.push(rec{p, dis[p][cur.use + 1], cur.use + 1});
}
q = pre[q];
}
}
}
int main () {
read(n); read(m); read(t);
read(ss); read(st);
for (int i = 1; i <= m; i++) {
int x, y, z;
read(x); read(y); read(z);
connect(x, y, z);
connect(y, x, z);
}
dijkstra();
int ans = INF;
for (int i = 0; i <= t; i++) ans = min(ans, dis[st][i]);
printf("%d\n", ans);
return 0;
}