题目大意:最短路,可以有$k$条边无费用
题解:分层图最短路,建成$k$层,层与层之间的边费用为$0$
卡点:空间计算出错,建边写错
C++ Code:
#include <cstdio> #include <queue> #define __N__ 10010 #define __K__ 11 #define __M__ 50010 #define maxn (__N__ * __K__) #define maxm (__M__ * __K__ << 1) int head[maxn], cnt; struct Edge { int to, nxt, w; } e[maxm << 1]; inline void add(int a, int b, int c) { e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt; } inline void addE(int a, int b, int c) { add(a, b, c); add(b, a, c); } int n, m, k, S, T; int d[maxn]; bool vis[maxn]; struct Dis { int pos, d; inline Dis() {} inline Dis(int __pos, int __d) {pos = __pos, d = __d;} inline friend bool operator < (const Dis &lhs, const Dis &rhs) { return lhs.d > rhs.d; } }; std::priority_queue<Dis> q; void dijkstra() { __builtin_memset(d, 0x3f, sizeof d); q.push(Dis(S, d[S] = 0)); while (!q.empty()) { int u = q.top().pos; q.pop(); if (u == T) return ; if (vis[u]) continue; vis[u] = true; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (d[v] > d[u] + e[i].w) { d[v] = d[u] + e[i].w; q.push(Dis(v, d[v])); } } } } int main() { scanf("%d%d%d%d%d", &n, &m, &k, &S, &T); for (int i = 0, a, b, c; i < m; i++) { scanf("%d%d%d", &a, &b, &c); for (int j = 0; j <= k; j++) addE(n * j + a, n * j + b, c); for (int j = 0; j < k; j++) add(n * j + a, n * (j + 1) + b, 0), add(n * j + b, n * (j + 1) + a, 0); } T += n * k; dijkstra(); printf("%d ", d[T]); return 0; }