This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 200005;
const int maxlg = 20;
const ll inf = 1LL << 60;
vector<pair<int, ll>> adj [maxn];
ll height [maxn];
int lvl [maxn];
ll dp [maxn];
bool store [maxn];
int start_time [maxn];
int end_time [maxn];
int cur_time;
void build_dp (int vertex, int parent, ll cur_height) {
cur_time++;
start_time[vertex] = cur_time;
height[vertex] = cur_height;
lvl[vertex] = lvl[parent] + 1;
for (pair<int, ll> nxt : adj[vertex]) {
if (nxt.first != parent) {
build_dp(nxt.first, vertex, cur_height + nxt.second);
}
}
if (store[vertex]) {
dp[vertex] = height[vertex];
} else {
dp[vertex] = inf;
for (pair<int, ll> nxt : adj[vertex]) {
if (nxt.first != parent) {
dp[vertex] = min(dp[vertex], dp[nxt.first]);
}
}
}
end_time[vertex] = cur_time;
}
bool is_parent (int u, int par) {
return start_time[par] <= start_time[u] && end_time[u] <= end_time[par];
}
int jmp [maxn][maxlg];
ll ans_jmp [maxn][maxlg];
void build_jmp (int vertex, int parent) {
jmp[vertex][0] = parent;
if (dp[vertex] == inf) {
ans_jmp[vertex][0] = inf;
} else {
ans_jmp[vertex][0] = dp[vertex] - 2 * height[vertex];
}
for (int i = 1; i < maxlg; i++) {
jmp[vertex][i] = jmp[jmp[vertex][i - 1]][i - 1];
ans_jmp[vertex][i] = min(ans_jmp[vertex][i - 1], ans_jmp[jmp[vertex][i - 1]][i - 1]);
}
for (pair<int, ll> nxt : adj[vertex]) {
if (nxt.first != parent) {
build_jmp(nxt.first, vertex);
}
}
}
ll query (int vertex, int forb) {
if (!is_parent(vertex, forb)) {
return -1;
}
ll cur_h = height[vertex];
int diff = lvl[vertex] - lvl[forb];
ll ans = inf;
for (int i = maxlg - 1; i >= 0; i--) {
if (diff & 1 << i) {
ans = min(ans, ans_jmp[vertex][i]);
vertex = jmp[vertex][i];
}
}
ans = min(ans, ans_jmp[vertex][0]);
if (ans != inf) {
ans += cur_h;
}
return ans;
}
int main () {
int vertexc, storec, queryc, root;
cin >> vertexc >> storec >> queryc >> root;
vector<pair<int, int>> edges;
for (int i = 0; i < vertexc - 1; i++) {
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back(make_pair(v, w));
adj[v].push_back(make_pair(u, w));
edges.push_back(make_pair(u, v));
}
for (int i = 0; i < storec; i++) {
int x;
cin >> x;
store[x] = true;
}
build_dp(root, root, 0);
build_jmp(root, root);
for (int i = 0; i < vertexc - 1; i++) {
if (lvl[edges[i].first] < lvl[edges[i].second]) {
swap(edges[i].first, edges[i].second);
}
}
for (int i = 0; i < queryc; i++) {
int forb_id, cur_vertex;
cin >> forb_id >> cur_vertex;
ll ans = query(cur_vertex, edges[forb_id - 1].first);
if (ans == -1) {
cout << "escaped" << '\n';
} else if (ans == inf) {
cout << "oo" << '\n';
} else {
cout << ans << '\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... |