#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e5 + 50, lgN = 22;
ll par[N], lifting1[N][lgN], lifting2[N][lgN], lifting3[N][lgN], nv[N], shop[N], depth[N], inf = 1e18;
int n, s, q, e;
vector<pair<int, ll>> G[N];
void dfs(int s, int p, ll w) {
par[s] = p;
depth[s] = depth[p] + 1;
lifting2[s][0] = w;
nv[s] = (shop[s] ? 0 : inf);
for (auto u : G[s]) {
if (u.first == p) continue;
dfs(u.first, s, u.second);
nv[s] = min(nv[s], nv[u.first] + u.second);
}
}
int kth_parent(int node, int k) {
if (k > n) { return -1; }
int at = node;
for (int pow = 0; pow <= lgN; pow++) {
if ((k & (1 << pow)) != 0) {
at = lifting1[at][pow];
if (at == -1) { break; }
}
}
return at;
}
int lca(int n1, int n2) {
if (depth[n1] < depth[n2]) { return lca(n2, n1); }
n1 = kth_parent(n1, depth[n1] - depth[n2]);
if (n1 == n2) {
return n2;
}
for (int i = lgN; i >= 0; i--) {
if (lifting1[n1][i] != lifting1[n2][i]) {
n1 = lifting1[n1][i];
n2 = lifting1[n2][i];
}
}
return lifting1[n1][0];
}
int main()
{
// ifstream cin("input.txt");
// ofstream cout("output.txt");
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> s >> q >> e;
vector<pair<int, int>> edges;
for (int i = 0; i < n - 1; i++) {
int a, b, w; cin >> a >> b >> w;
G[a].push_back({b, w});
G[b].push_back({a, w});
edges.push_back({a, b});
}
while(s--) {
int c; cin >> c;
shop[c] = 1;
}
dfs(e, e, 0);
for (auto& [a, b] : edges) {
if (depth[a] < depth[b]) swap(a, b);
}
for (int i = 1; i <= n; i++) {
lifting1[i][0] = par[i];
lifting3[i][0] = min(nv[i], nv[par[i]] + lifting2[i][0]);
}
for (int lg = 1; lg < lgN; lg++) {
for (int i = 1; i <= n; i++) {
lifting1[i][lg] = lifting1[lifting1[i][lg - 1]][lg - 1];
lifting2[i][lg] = lifting2[lifting1[i][lg - 1]][lg - 1] + lifting2[i][lg - 1];
lifting3[i][lg] = min(lifting3[i][lg - 1], lifting3[lifting1[i][lg - 1]][lg - 1] + lifting2[i][lg - 1]);
}
}
while(q--) {
int i, r; cin >> i >> r;
int u = edges[i - 1].first;
if (lca(u, r) == u) {
int w = depth[r] - depth[u];
ll res = nv[r], curdist = 0;
for (int lg = 0; lg < lgN; lg++) {
if (w % 2) {
res = min(res, lifting3[r][lg] + curdist);
curdist += lifting2[r][lg];
r = lifting1[r][lg];
}
w /= 2;
}
if (res >= inf) cout << "oo\n";
else cout << res << '\n';
} else {
cout << "escaped\n";
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |