You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
6.4 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
/*
便 A
d
x y
Δe=ex,y+dydx x x y Δe x Δe y
x
x x
Dijkstra S rt[S]
dS+Δe
y x y
y y
A
 16ms,A*10
2022-10-11 
*/
const int N = 1e3 + 10, M = 1e5 + 10;
struct Leftist_Tree {
int tot, rt[N];
struct node {
int dis, lc, rc, x, val;
} t[N * 45];
Leftist_Tree() {
t[0].dis = -1;
}
inline int merge(int x, int y) {
if (!x || !y) return x | y;
if (t[x].val > t[y].val) swap(x, y);
int p = ++tot;
t[p] = t[x], t[p].rc = merge(t[x].rc, y);
if (t[t[p].lc].dis < t[t[p].rc].dis) swap(t[p].lc, t[p].rc);
t[p].dis = t[t[p].rc].dis + 1;
return p;
}
inline void insert(int &p, int x, int v) {
++tot, t[tot] = {0, 0, 0, x, v};
p = merge(p, tot);
}
} L;
struct Kth_Path {
int n, m, S, T, K;
int head[N], ver[M], edge[M], Next[M], tot;
int rh[N], rv[M], re[M], rn[M], rt;
int d[N], fa[N];
bool v[N], vis[N], ot[M];
inline void add(int x, int y, int z) {
ver[++tot] = y;
edge[tot] = z;
Next[tot] = head[x];
head[x] = tot;
}
inline void add_r(int x, int y, int z) {
rv[++rt] = y;
re[rt] = z;
rn[rt] = rh[x];
rh[x] = rt;
}
struct node {
int x, v;
inline bool operator<(node a) const {
return v > a.v;
}
};
inline void dijkstra() {
memset(d, 0x3f, sizeof(int) * (n + 1));
memset(vis, false, sizeof(bool) * (n + 1));
priority_queue<node> q;
d[T] = 0;
q.push({T, 0});
while (!q.empty()) {
int x = q.top().x;
q.pop();
if (vis[x]) continue;
vis[x] = true;
for (int i = rh[x]; i; i = rn[i]) {
int y = rv[i], z = re[i];
if (d[y] > d[x] + z) d[y] = d[x] + z, q.push({y, d[y]});
}
}
}
inline void init() {
tot = rt = 0;
memset(head, 0, sizeof head);
memset(rh, 0, sizeof rh);
}
inline void bfs1() {
queue<int> q;
memset(ot, false, sizeof ot);
memset(v, false, sizeof v);
v[T] = true, q.push(T);
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = rh[x]; i; i = rn[i]) {
int y = rv[i], z = re[i];
if (v[y] || d[y] != d[x] + z) continue;
fa[y] = x, v[y] = ot[i] = true, q.push(y);
}
}
}
inline void bfs2() {
queue<int> q;
memset(v, false, sizeof v);
v[T] = true, q.push(T);
while (q.size()) {
int x = q.front();
q.pop();
if (fa[x]) L.rt[x] = L.merge(L.rt[x], L.rt[fa[x]]);
for (int i = rh[x]; i; i = rn[i])
if (ot[i] && !v[rv[i]]) v[rv[i]] = true, q.push(rv[i]);
}
}
inline int solve() {
cin >> n >> m;
init();
for (int i = 1; i <= m; i++) {
int x, y, z;
cin >> x >> y >> z;
add(x, y, z), add_r(y, x, z);
}
cin >> S >> T >> K;
if (S == T) K++;
dijkstra();
if (!vis[S]) return -1;
if (K == 1) return d[S];
bfs1();
for (int x = 1; x <= n; x++) {
if (!vis[x]) continue;
for (int i = head[x]; i; i = Next[i])
if (!ot[i] && vis[ver[i]])
L.insert(L.rt[x], ver[i], d[ver[i]] + edge[i] - d[x]);
}
bfs2();
priority_queue<node> q;
if (L.rt[S]) q.push({L.rt[S], d[S] + L.t[L.rt[S]].val});
K--;
while (q.size()) {
node t = q.top();
q.pop();
if (!--K) return t.v;
if (L.t[t.x].lc) q.push({L.t[t.x].lc, t.v - L.t[t.x].val + L.t[L.t[t.x].lc].val});
if (L.t[t.x].rc) q.push({L.t[t.x].rc, t.v - L.t[t.x].val + L.t[L.t[t.x].rc].val});
if (L.rt[L.t[t.x].x]) q.push({L.rt[L.t[t.x].x], t.v + L.t[L.rt[L.t[t.x].x]].val});
}
return -1;
}
} K;
int main() {
//加快读入
cin.tie(0), ios::sync_with_stdio(false);
printf("%d\n", K.solve());
return 0;
}