1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include<bits/stdc++.h> using namespace std; using LL = long long; const int N = 2e6 + 5, MOD = 99824435;
int n, k, p, s, t; struct Edge { int u, v, w; } G[1000005]; int dep[1000005]; struct Node { LL v, w; bool operator < (const Node &o) const { return w > o.w; } }; LL dis[N]; bool vis[N]; int head1[N], ver1[N], Next[N], tot1; void add_edge1(int u, int v) { ver1[++ tot1] = v; Next[tot1] = head1[u]; head1[u] = tot1; } int head2[N * 3], ver2[N * 3], Next2[N * 3], val[N * 3], tot2; void add_edge2(int u, int v, int w) { ver2[++ tot2] = v; val[tot2] = w; Next[tot2] = head2[u]; head2[u] = tot2; } void dfs(int x, int p) { dep[x] = dep[p] + 1; for (int i = head1[x]; i; i = Next[i]) { int y = ver1[i]; if (y ^ p) { dfs(y, x); } } } priority_queue< Node > q; void dijkstra(int st, int ed) { for (int i = 0; i <= n * 2; ++ i) { dis[i] = 1e14; vis[i] = false; } while (!q.empty()) { q.pop(); } q.push({st, dis[st] = 0}); while (!q.empty()) { Node p = q.top(); q.pop(); if (vis[p.v]) { continue; } vis[p.v] = true; for (int i = head2[p.v]; i; i = Next[i]) { LL v = ver2[i], w = val[i]; if (!vis[v] && dis[v] > dis[p.v] + w) { q.push({v, dis[v] = dis[p.v] + w}); } } } } void solve() { scanf("%d", &n); for (int i = 0; i <= tot1; ++ i) { head1[i] = 0; } for (int i = 0; i <= tot2; ++ i) { head2[i] = 0; } tot1 = tot2 = 0; for (int i = 1; i < n; ++ i) { scanf("%d %d %d", &G[i].u, &G[i].v, &G[i].w); add_edge1(G[i].u, G[i].v); add_edge1(G[i].v, G[i].u); } dfs(1, 0); for (int i = 1; i < n; ++ i) { int u = G[i].u, v = G[i].v, w = G[i].w; add_edge2(u, v, w); add_edge2(v, u, w); } scanf("%d %d", &k, &p); for(int i = 1;i <= n; ++ i){ add_edge2(dep[i] + n, i, 0); } scanf("%d %d", &s, &t); for (int i = 1; i <= n; ++ i) { int l = dep[i] - k; if (l >= 1){ add_edge2(i, l + n, p); } int r = dep[i] + k; if (r <= n){ add_edge2(i, r + n, p); } } dijkstra(s, t); printf("%lld\n", dis[t]); } signed main() { int t; scanf("%d", &t); while (t -- ) { solve(); } return 0; }
|