제출 #558625

#제출 시각아이디문제언어결과실행 시간메모리
558625SortingValley (BOI19_valley)C++17
100 / 100
264 ms51720 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; template<class T> void check_min(T &a, const T &b){ a = (a < b) ? a : b; } template<class T> void check_max(T &a, const T &b){ a = (a > b) ? a : b; } #define all(x) (x).begin(), (x).end() const ll INF = 1e18; const ll N = 1e5 + 3; const ll MX = 1e15; const int LOGN = 20; int n, s, q, e; vector<pair<int, ll>> adj[N]; bool shop[N]; int d[N], par[N]; ll up[LOGN][N], min_up[LOGN][N], mdist[N]; ll droot[N]; int lca(int u, int v){ if(d[u] != d[v]){ if(d[u] < d[v]) swap(u, v); int diff = d[u] - d[v]; for(int i = LOGN - 1; i >= 0; --i){ if(diff >> i & 1){ u = par[up[i][u]]; } } } if(u == v) return u; for(int i = LOGN - 1; i >= 0; --i){ if(par[up[i][u]] != par[up[i][v]]){ u = par[up[i][u]]; v = par[up[i][v]]; } } return par[u]; } void init_up(){ for(int i = 1; i <= n; ++i){ up[0][i] = i; min_up[0][i] = mdist[i] - droot[i]; } for(int j = 1; j < LOGN; ++j){ for(int i = 1; i <= n; ++i){ up[j][i] = up[j - 1][par[up[j - 1][i]]]; min_up[j][i] = min(min_up[j - 1][i], min_up[j - 1][par[up[j - 1][i]]]); } } } void dfs(int u, int p){ par[u] = p; mdist[u] = shop[u] ? 0 : INF; for(auto [to, w]: adj[u]){ if(to == p) continue; d[to] = d[u] + 1; droot[to] = droot[u] + w; dfs(to, u); check_min(mdist[u], mdist[to] + w); } } array<int, 3> edges[N]; int main(){ ios::sync_with_stdio(false); cin.tie(NULL); cin >> n >> s >> q >> e; for(int i = 0; i < n - 1; ++i){ int u, v, w; cin >> u >> v >> w; adj[u].push_back({v, w}); adj[v].push_back({u, w}); edges[i + 1] = {u, v, w}; } for(int i = 0; i < s; ++i){ int c; cin >> c; shop[c] = true; } dfs(e, e); init_up(); for(int i = 1; i <= n - 1; ++i){ if(d[edges[i][0]] < d[edges[i][1]]) swap(edges[i][0], edges[i][1]); } for(int i = 0; i < q; ++i){ int idx, r; cin >> idx >> r; if(lca(edges[idx][0], r) != edges[idx][0]){ cout << "escaped\n"; continue; } ll ans = INF; int target_d = d[edges[idx][0]]; int curr_d = d[r]; int num_nodes = curr_d - target_d + 1; int cd = r; for(int i = LOGN - 1; i >= 0; --i) if(num_nodes >> i & 1){ check_min(ans, droot[r] + min_up[i][cd]); cd = par[up[i][cd]]; } if(ans >= MX){ cout << "oo\n"; } else{ cout << ans << "\n"; } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...