#include <bits/stdc++.h>
bool M1;
#define int long long
#define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define REV(i, a, b) for (int i = (a), _b = (b); i >= _b; --i)
using namespace std;
#define MAXN 100005
int numNode, numShop, numQuery, exitNode;
vector<pair<int, int>> g[MAXN];
bool shop[MAXN];
int par[MAXN];
int dep[MAXN];
int up[MAXN][20];
int sumShop[MAXN];
int closest[MAXN];
int sumw[MAXN];
pair<int, int> edge[MAXN];
int heavy[MAXN], child[MAXN], pos[MAXN], head[MAXN], timer = 0;
struct SMT {
int n;
vector<int> st;
SMT(int _n = 0) {
n = _n;
st.assign((n << 2) + 5, 1e15);
}
void update(int id, int l, int r, int p, int val) {
if (l == r) return st[id] = min(st[id], val), void();
int mid = (l + r) >> 1;
if (p <= mid) update(id << 1, l, mid, p, val);
else update(id << 1 | 1, mid + 1, r, p, val);
st[id] = min(st[id << 1], st[id << 1 | 1]);
}
void update(int p, int val) {
update(1, 1, n, p, val);
}
int get(int id, int l, int r, int u, int v) {
if (v < l || r < u) return 1e15;
if (u <= l && r <= v) return st[id];
int mid = (l + r) >> 1;
return min(get(id << 1, l, mid, u, v), get(id << 1 | 1, mid + 1, r, u, v));
}
int get(int u, int v) {
return get(1, 1, n, u, v);
}
} tree;
///++++++++++++++++++++++++++++++++++++++///
void dfs(int u, int p) {
sumShop[u] = shop[u];
int mx_c = 0;
child[u] = 1;
for (pair<int, int> &x : g[u]) {
int v, w; tie(v, w) = x;
if (v == p) continue;
par[v] = u;
up[v][0] = u;
sumw[v] = sumw[u] + w;
dep[v] = dep[u] + 1;
dfs(v, u);
child[u] += child[v];
sumShop[u] += sumShop[v];
if (child[v] > mx_c) {
mx_c = child[v];
heavy[u] = v;
}
}
}
void hld(int u, int h) {
pos[u] = ++timer;
head[u] = h;
if (heavy[u] != 0) hld(heavy[u], h);
for (pair<int, int> &x : g[u]) {
int v, w; tie(v, w) = x;
if (v == par[u] || v == heavy[u]) continue;
hld(v, v);
}
}
void prepare_LCA() {
FOR(j, 1, 19) {
FOR(i, 1, numNode) up[i][j] = up[up[i][j - 1]][j - 1];
}
}
int LCA(int a, int b) {
if (dep[a] < dep[b]) swap(a, b);
int h = dep[a] - dep[b];
for (int i = 0; (1 << i) <= h; ++i) {
if (h >> i & 1) a = up[a][i];
}
if (a == b) return a;
h = __lg(dep[a]);
for (int i = h; i >= 0; --i) {
if (up[a][i] != up[b][i]) {
a = up[a][i];
b = up[b][i];
}
}
return up[a][0];
}
int dist(int u, int v) {
return dep[u] + dep[v] - 2 * dep[LCA(u, v)];
}
void DP(int u, int p) {
closest[u] = (shop[u] ? 0 : 1e15);
for (pair<int, int> &x : g[u]) {
int v, w; tie(v, w) = x;
if (v == p) continue;
DP(v, u);
closest[u] = min(closest[u], closest[v] + w);
}
}
int get(int u, int v) {
int res = 1e15;
while (head[u] != head[v]) {
if (dep[head[u]] < dep[head[v]]) swap(u, v);
res = min(res, tree.get(pos[head[u]], pos[u]));
u = par[head[u]];
}
if (pos[u] > pos[v]) swap(u, v);
res = min(res, tree.get(pos[u], pos[v]));
return res;
}
void solve() {
cin >> numNode >> numShop >> numQuery >> exitNode;
FOR(i, 1, numNode - 1) {
int u, v, w; cin >> u >> v >> w;
g[u].push_back(make_pair(v, w));
g[v].push_back(make_pair(u, w));
edge[i] = make_pair(u, v);
}
FOR(i, 1, numShop) {
int curNode; cin >> curNode;
shop[curNode] = true;
}
dfs(exitNode, 0);
DP(exitNode, 0);
hld(exitNode, exitNode);
prepare_LCA();
tree = SMT(numNode);
FOR(i, 1, numNode) {
tree.update(pos[i], closest[i] - sumw[i]);
}
FOR(i, 1, numNode - 1) {
if (par[edge[i].first] == edge[i].second) swap(edge[i].first, edge[i].second);
}
FOR(Nium, 1, numQuery) {
int I, R; cin >> I >> R;
int u, v; tie(u, v) = edge[I];
if (dep[R] == dep[u] + 1 + dist(v, R)) {
if (sumShop[v] == 0) cout << "oo\n";
else {
cout << sumw[R] + get(v, R) << '\n';
}
} else cout << "escaped\n";
}
}
///++++++++++++++++++++++++++++++++++++++///
#define task "test"
int32_t main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
solve();
return 0;
}
| # | 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... |