제출 #259016

#제출 시각아이디문제언어결과실행 시간메모리
259016FalconValley (BOI19_valley)C++14
100 / 100
396 ms57388 KiB
#pragma GCC optimize("O2") #include <bits/stdc++.h> #ifdef DEBUG #include "debug.hpp" #endif using namespace std; #define all(c) (c).begin(), (c).end() #define traverse(c, it) for(auto it = (c).begin(); it != (c).end(); it++) #define rep(i, N) for(int i = 0; i < (N); i++) #define rep1(i, N) for(int i = 1; i <= (N); i++) #define rep2(i, s, e) for(int i = (s); i <= (e); i++) #define rep3(i, s, e, d) for(int i = (s); (d) >= 0 ? i <= (e) : i >= (e); i += (d)) #define pb push_back #ifdef DEBUG #define debug(x...) {dbg::depth++; string dbg_vals = dbg::to_string(x); dbg::depth--; dbg::fprint(__func__, __LINE__, #x, dbg_vals);} #define light_debug(x) {dbg::light = 1; dbg::dout << __func__ << ":" << __LINE__ << " " << #x << " = " << x << endl; dbg::light = 0;} #else #define debug(x...) #define light_debug(x) #endif using ll = long long; using pii = pair<int, int>; using vi = vector<int>; struct edge{ int u, v, w; }; int N, S, Q, E; vector<vector<edge>> adj; vector<edge> edges; vector<vi> par, RMQ_set; vi is_shop, dp_set, in_time, out_time; vector<ll> dp, dist; vector<vector<ll>> RMQ; void init(){ adj.resize(N); dist.resize(N); dp.resize(N); is_shop.resize(N); dp_set.resize(N); in_time.resize(N); out_time.resize(N); edges.resize(N - 1); par = vector<vi>(N, vi(__lg(N) + 1, E)); RMQ = vector<vector<ll>>(N, vector<ll>(__lg(N) + 1)); RMQ_set = vector<vi>(N, vi(__lg(N) + 1)); } int cur_time = 0; void dfs(int v, int p, ll d){ in_time[v] = cur_time++; debug(v); par[v][0] = p, dist[v] = d; if(is_shop[v]) dp[v] = -d, dp_set[v] = 1; for(auto e : adj[v]){ int u = v ^ e.v ^ e.u; if(u != p){ dfs(u, v, d + e.w); if(dp_set[u]){ if(!dp_set[v]) dp[v] = dp[u] + 2 * e.w, dp_set[v] = 1; else dp[v] = min(dp[v], dp[u] + 2 * e.w); } } } out_time[v] = cur_time; } inline bool is_ancestor(int u, int v){ return in_time[u] <= in_time[v] && out_time[v] <= out_time[u]; } inline void xmin(ll a, int set_a, ll b, int set_b, ll& c, int& set_c){ set_c = set_a || set_b; if(set_a && set_b) c = min(a, b); else if(set_a) c = a; else if(set_b) c = b; } void init_RMQ(){ rep1(k, __lg(N)) rep(i, N) par[i][k] = par[par[i][k - 1]][k - 1]; rep(i, N) RMQ_set[i][0] = dp_set[i], RMQ[i][0] = dp[i]; rep1(k, __lg(N)) rep(i, N) xmin(RMQ[i][k - 1], RMQ_set[i][k - 1], RMQ[par[i][k - 1]][k - 1], RMQ_set[par[i][k - 1]][k - 1], RMQ[i][k], RMQ_set[i][k]); } pair<int, ll> nearest_shop(int r, int t){ assert(is_ancestor(t, r)); debug(r, t); ll d = dist[r]; ll ans = -1; int set_ans = 0; int k = __lg(N); while(r != t){ int x = par[r][k]; debug(x, k); if(!is_ancestor(x, par[t][0])) xmin(RMQ[r][k], RMQ_set[r][k], ans, set_ans, ans, set_ans), r = x; k--; } xmin(ans, set_ans, RMQ[t][0], RMQ_set[t][0], ans, set_ans); return {set_ans, ans + d}; } signed main(){ ios_base::sync_with_stdio(false); cin.tie(0), cout.tie(0); #ifdef DEBUG freopen("debug", "w", stderr); #endif cin >> N >> S >> Q >> E; E--; init(); rep(i, N - 1){ cin >> edges[i].u >> edges[i].v >> edges[i].w; edges[i].u--, edges[i].v--; adj[edges[i].u].pb(edges[i]), adj[edges[i].v].pb(edges[i]); } rep(i, S){ int v; cin >> v; is_shop[--v] = 1; } dfs(E, E, 0); init_RMQ(); rep(i, Q){ int e, r; cin >> e >> r; --e, --r; int t = dist[edges[e].u] < dist[edges[e].v] ? edges[e].v : edges[e].u; if(!is_ancestor(t, r)) cout << "escaped\n"; else{ auto p = nearest_shop(r, t); cout << (p.first ? to_string(p.second) : "oo") << '\n'; } } #ifdef DEBUG dbg::dout << "\nExecution time: " << clock() << "ms\n"; #endif return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...