题目大意:最短路,可以有$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\n", d[T]);
return 0;
}