洛谷P4568 分層圖最短路
阿新 • • 發佈:2020-08-12
題意: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; }