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 <vector>
#include <algorithm>
#include <iostream>
#include <set>
#include <cmath>
#include <map>
#include <random>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <queue>
#include <limits.h>
using namespace std;
class Tree {
private:
int root;
vector<vector<pair<int,int>>> adj; //node, weight
vector<int> parent;
vector<int> depth;
map<pair<int,int>,int> weight;
vector<bool> isVillage;
vector<int> sub, pre, post;
public:
Tree (int N, int root) {
adj.resize(N);
this->root = root;
parent.resize(N);
depth.resize(N);
isVillage.assign(N, false);
sub.resize(N);
pre.resize(N), post.resize(N);
}
void add_edge (int u, int v, int w) {
adj[u].push_back({v, w});
adj[v].push_back({u, w});
weight[{u, v}] = weight[{v, u}] = w;
}
void update_village (int u) {
isVillage[u] = true;
}
int cntr = 0;
void dfs (int curNode, int prevNode) {
parent[curNode] = prevNode;
sub[curNode] = -1;
pre[curNode] = cntr++;
for (pair<int,int> p: adj[curNode]) {
if (p.first != prevNode) {
dfs(p.first, curNode);
if (sub[p.first] != -1) {
if (sub[curNode] == -1) sub[curNode] = INT_MAX;
sub[curNode] = min(sub[p.first] + weight[{curNode, p.first}], sub[curNode]);
}
}
}
if (curNode == root) {
depth[curNode] = 0;
} else {
depth[curNode] = depth[prevNode] + weight[{curNode, prevNode}];
}
if (isVillage[curNode]) {
sub[curNode] = 0;
}
post[curNode] = cntr++;
}
bool isAncestor (int a, int b) {
//is a an ancestor of b?
return (pre[a] <= pre[b] && post[a] >= post[b]);
}
int chmin (int a, int b) {
if (a == -1) return b;
if (b == -1) return a;
return min(a, b);
}
void query (int a1, int a2, int b) {
if (parent[a1] != a2) {
swap(a1, a2);
}
//parent[a1] = a2
if (!isAncestor(a1, b)) {
cout << "escaped\n";
return;
}
int x = b;
int ans = -1;
int delta = 0;
while (x != a2) {
//cout << b << " " << x << " " << sub[x] << " " << abs(depth[x] - depth[b]) << '\n';
if (sub[x] != -1) {
ans = chmin(ans, sub[x] + delta);
}
delta += weight[{x, parent[x]}];
x = parent[x];
}
if (ans == -1) {
cout << "oo\n";
return;
}
cout << ans << '\n';
}
void read () {
dfs(root, -1);
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, S, Q, E;
cin >> N >> S >> Q >> E;
E--;
Tree myTree(N, E);
vector<pair<int,int>> edges;
for (int i = 0; i < N - 1; i++) {
int u, v, w;
cin >> u >> v >> w;
u--, v--;
edges.emplace_back(u, v);
myTree.add_edge(u, v, w);
}
while (S--) {
int x; cin >> x; x--;
myTree.update_village(x);
}
myTree.read();
while (Q--) {
int u, v;
cin >> u >> v;
u--, v--;
myTree.query(edges[u].first, edges[u].second, v);
}
}
# | 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... |