分层图最短路
注意:priority_queue默认排序序列是从大到小的,所以重载小于符号时要a>b
以后权值一律写w,不要用v或c!
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define fo(i, j, k) for (i=(j);i<=(k);i++)
#define fd(i, k, j) for (i=(k);i>=(j);i--)
#define fg(i, u) for (i=0;i<G[u].size();i++)
#define fe(i, u) for (i=head[u];i!=-1;i=e[i].next)
#define rd(a) scanf("%d", &a)
#define rd2(a, b) scanf("%d%d", &a, &b)
#define rd3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define ms(i, j) memset(i, j, sizeof i)
#define FN2 "bzoj2763"
using namespace std;
const int MAXN = 1200100, INF = 0x3f3f3f3f;
struct edge{int v, c;}e[MAXN<<2];
struct data {
int u, c;
bool operator < (data const &b) const {
return c>b.c;
}
};
int n, m, k, en, dis[MAXN], s, t, vi[MAXN];
vector<int> G[MAXN];
void ins(int u, int v, int c) {
en++, e[en].v = v, e[en].c = c, G[u].push_back(en);
}
void pre() {
int i; en = 0;
fo (i, 0, n*(k+2)) G[i].clear(), dis[i] = INF, vi[i] = false;
}
void init() {
int i,j;
pre();
rd2(s, t);
fo (i, 1, m) {
int a, b, c;
rd3(a, b, c);
fo (j, 0, k) {
ins(a+j*n, b+j*n, c), ins(b+j*n, a+j*n, c);
if (j!=k) ins(a+j*n, b+(j+1)*n, 0), ins(b+j*n, a+(j+1)*n, 0);
}
}
}
void solve() {
int i, ans = INF;
priority_queue<data> q;
dis[s] = 0, q.push((data){s, dis[s]});
while (!q.empty()) {
data p = q.top(); q.pop();
int u = p.u;
if (vi[u]) continue;
vi[u] = true;
for (i=0;i<G[u].size();i++) {
int v = e[G[u][i]].v;
if (dis[v]>dis[u]+e[G[u][i]].c) {
dis[v] = dis[u]+e[G[u][i]].c;//用dis[u],因为有重边
q.push((data){v, dis[v]});
}
}
}
fo (i, 0, k) {
ans = min(ans, dis[t+i*n]);
}
printf("%d\n", ans);
}
int main() {
#ifndef ONLINE_JUDGE
freopen(FN2".in","r",stdin);freopen("1.out","w",stdout);
#endif
while (rd3(n,m,k)==3) init(), solve();
return 0;
}