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 <bits/stdc++.h>
using namespace std;
using ll = long long;
int n, s, q, e;
struct Edge {
int b;
ll w;
int i;
};
vector<vector<Edge> > adj;
vector<int> paren;
vector<int> start;
vector<int> en;
vector<bool> is_shop;
vector<pair<int, int> > edges;
vector<ll> dist; // dist from root;
vector<ll> magic;
// SET PARENT NODES AND START AND END TIMEs
void dfs(int node, int &cnt, int par = 0) {
start[node] = cnt++; // increment count yep
int add = 0;
for(auto neigh : adj[node]) {
if(neigh.b == par) continue;
paren[neigh.b] = node;
dist[neigh.b] = dist[node] + neigh.w;
dfs(neigh.b, cnt, node);
}
en[node] = cnt++;
}
// this is quite tuff
void compute_magic(int node, int par = 0) {
for(auto neigh : adj[node]) {
if(neigh.b == par) continue;
compute_magic(neigh.b, node);
}
if(is_shop[node]) magic[node] = dist[node];
else magic[node] = LLONG_MAX;
for(auto neigh : adj[node]) {
if(neigh.b == par) continue;
magic[node] = min(magic[node], magic[neigh.b]);
}
}
const int MAXN = 1e5 + 5;
const int MAXD = 18;
int jumpVert[MAXN][MAXD];
ll jumpMagic[MAXN][MAXD];
void buildLifting() {
for(int i = 1; i <= n; i++) {
jumpVert[i][0] = paren[i];
jumpMagic[i][0] = magic[i];
}
for(int d = 1; d < MAXD; d++) {
for(int i = 1; i <= n; i++) {
jumpVert[i][d] = jumpVert[jumpVert[i][d - 1]][d - 1];
jumpMagic[i][d] = min(jumpMagic[i][d - 1], jumpMagic[jumpMagic[i][d-1]][d-1]);
}
}
}
void solve() {
cin >> n >> s >> q >> e;
adj.resize(n + 1);
start.resize(n + 1);
en.resize(n + 1);
paren.resize(n + 1);
is_shop.resize(n + 1);
dist.resize(n + 1);
magic.resize(n + 1);
for(int i = 0; i < n - 1; i++) {
int a, b, w; cin >> a >> b >> w;
adj[a].push_back({b, w, i + 1});
adj[b].push_back({a, w, i + 1});
edges.push_back({a, b});
}
int cnt = 0;
dfs(e, cnt);
// for(int i = 1; i <= n; i++) {
// cout << start[i] << ' ' << en[i] << '\n';
// }
for(int i = 0; i < s; i++) {
int c; cin >> c;
is_shop[c] = true;
}
compute_magic(e);
for(int i = 1; i <= n; i++) {
if(magic[i] != LLONG_MAX) magic[i] = magic[i] - (2LL) * dist[i];
}
buildLifting();
while(q--) {
int i, r; cin >> i >> r;
int par = edges[i - 1].first, child = edges[i - 1].second;
if(paren[par] == child) swap(par, child); // paren[child] = par woohoo
// cout << par << ',' << child << '\n';
if(!(start[child] <= start[r] && en[r] <= en[child])) {
cout << "escaped\n";
continue;
}
// now the hard part ... we need dist have that ...
// now we need this magic crap ...
// answer to query -> dist[r] + min_w magic[w] for all w -> r -> child
int curr_vert = r;
ll ans = magic[child];
for(int d = 0; d < MAXD; d++) {
int vert = jumpVert[curr_vert][d];
if(start[child] <= start[vert] && en[vert] <= en[child]) { // vertex is a child of the goon
ans = min(ans, jumpMagic[curr_vert][d]);
curr_vert = vert;
}
}
if(ans != LLONG_MAX) {
ans = ans + dist[r];
cout << ans << '\n';
} else cout << "oo\n";
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
#ifndef ONLINE_JUDGE
freopen("file.txt", "r", stdin);
#endif
int t = 1; // cin >> t;
while(t--) {
solve();
}
}
Compilation message (stderr)
valley.cpp: In function 'void dfs(int, int&, int)':
valley.cpp:27:9: warning: unused variable 'add' [-Wunused-variable]
27 | int add = 0;
| ^~~
valley.cpp: In function 'int main()':
valley.cpp:147:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
147 | freopen("file.txt", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |