Submission #494278

#TimeUsernameProblemLanguageResultExecution timeMemory
494278wiwihoValley (BOI19_valley)C++14
0 / 100
989 ms92636 KiB
#include <bits/stdc++.h> #include <bits/extc++.h> #define StarBurstStream ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define iter(a) a.begin(), a.end() #define riter(a) a.rbegin(), a.rend() #define lsort(a) sort(iter(a)) #define gsort(a) sort(riter(a)) #define pb(a) push_back(a) #define eb(a) emplace_back(a) #define pf(a) push_front(a) #define ef(a) emplace_front(a) #define pob pop_back() #define pof pop_front() #define mp(a, b) make_pair(a, b) #define F first #define S second #define mt make_tuple #define gt(t, i) get<i>(t) #define tomax(a, b) ((a) = max((a), (b))) #define tomin(a, b) ((a) = min((a), (b))) #define topos(a) ((a) = (((a) % MOD + MOD) % MOD)) #define uni(a) a.resize(unique(iter(a)) - a.begin()) #define printv(a, b) {bool pvaspace=false; \ for(auto pva : a){ \ if(pvaspace) b << " "; pvaspace=true;\ b << pva;\ }\ b << "\n";} using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef unsigned long long ull; typedef long double ld; using pii = pair<int, int>; using pll = pair<ll, ll>; using pdd = pair<ld, ld>; using tiii = tuple<int, int, int>; const ll MOD = 1000000007; const ll MAX = 2147483647; template<typename A, typename B> ostream& operator<<(ostream& o, pair<A, B> p){ return o << '(' << p.F << ',' << p.S << ')'; } ll ifloor(ll a, ll b){ if(b < 0) a *= -1, b *= -1; if(a < 0) return (a - b + 1) / b; else return a / b; } ll iceil(ll a, ll b){ if(b < 0) a *= -1, b *= -1; if(a > 0) return (a + b - 1) / b; else return a / b; } struct SegmentTree{ vector<ll> st; int sz; void init(int _sz){ sz = _sz; st.resize(sz * 4, MAX); } void modify(int x, int v, int L = -1, int R = -1, int id = 0){ if(L == -1) L = 0; if(R == -1) R = sz - 1; //cerr << "modify " << x << " " << v << " " << L << " " << R << " " << sz << "\n"; //assert(L <= R); if(L == R){ st[id] = v; return; } int M = (L + R) / 2; if(x <= M) modify(x, v, L, M, 2 * id + 1); else modify(x, v, M + 1, R, 2 * id + 2); st[id] = min(st[2 * id + 1], st[2 * id + 2]); } ll query(int l, int r, int L = -1, int R = -1, int id = 0){ if(l == -1) l = 0; if(r == -1) r = sz - 1; if(L == -1) L = 0; if(R == -1) R = sz - 1; if(l > r) return MAX; if(l <= L && R <= r) return st[id]; int M = (L + R) / 2; if(r <= M) return query(l, r, L, M, 2 * id + 1); else if(l > M) return query(l, r, M + 1, R, 2 * id + 2); else return min(query(l, r, L, M, 2 * id + 1), query(l, r, M + 1, R, 2 * id + 2)); } }; int n; vector<vector<pii>> g; vector<bool> shop; vector<vector<int>> pr, in, out; vector<vector<ll>> dpt; vector<SegmentTree> st; vector<map<int, int>> sub; vector<int> sz; vector<bool> del; vector<pii> e; int esc; void init(){ g.resize(n + 1); shop.resize(n + 1); pr.resize(n + 1); in.resize(n + 1); out.resize(n + 1); dpt.resize(n + 1); st.resize(n + 1); sub.resize(n + 1); sz.resize(n + 1); del.resize(n + 1); e.resize(n); } void dfsg(int now, int p){ sz[now] = 1; for(pii i : g[now]){ if(i.F == p || del[i.F]) continue; dfsg(i.F, now); sz[now] += sz[i.F]; } } int cen; void dfsg2(int now, int p, int t){ int mx = t - sz[now]; for(pii i : g[now]){ if(i.F == p || del[i.F]) continue; mx = max(mx, sz[i.F]); dfsg2(i.F, now, t); } if(mx <= t / 2) cen = now; } int ts; void dfssub(int now, int p, ll d){ sub[cen][now] = pr[now].size(); in[now].eb(++ts); pr[now].eb(cen); dpt[now].eb(d); if(shop[now]){ st[cen].modify(in[now].back(), d); } for(pii i : g[now]){ if(i.F == p || del[i.F]) continue; dfssub(i.F, now, d + i.S); } out[now].eb(ts); } void solve(int rt){ dfsg(rt, rt); dfsg2(rt, rt, sz[rt]); st[cen].init(sz[rt]); ts = -1; dfssub(cen, cen, 0); //cerr << "solve " << cen << " "; //printv(sub[cen], cerr); del[cen] = true; for(pii i : g[cen]){ if(!del[i.F]) solve(i.F); } } void query(int u1, int u2, int v){ for(int i = (int)pr[v].size() - 1; i >= 0; i--){ int cen = pr[v][i]; if(sub[cen].find(esc) == sub[cen].end()) continue; if(sub[cen].find(u1) == sub[cen].end() || sub[cen].find(u2) == sub[cen].end()){ cout << "escaped\n"; return; } int id1 = sub[cen][u1]; int id2 = sub[cen][u2]; int ide = sub[cen][esc]; if(in[u1][id1] > in[u2][id2]) swap(u1, u2), swap(id1, id2); //cerr << "escape " << v << " " << i << " " << cen << "\n"; if((in[u2][id2] <= in[v][i] && out[v][i] <= out[u2][id2]) || (in[u2][id2] <= in[esc][ide] && out[esc][ide] <= out[u2][id2])) break; cout << "escaped\n"; return; } ll ans = MAX; for(int i = (int)pr[v].size() - 1; i >= 0; i--){ int cen = pr[v][i]; if(sub[cen].find(u1) == sub[cen].end() || sub[cen].find(u2) == sub[cen].end()){ ans = min(ans, dpt[v][i] + st[cen].query(-1, -1)); continue; } int id1 = sub[cen][u1]; int id2 = sub[cen][u2]; if(in[u1][id1] > in[u2][id2]) swap(u1, u2), swap(id1, id2); //cerr << "query " << v << " " << cen << " " << u1 << " " << u2 << "\n" // << in[u2][id2] << " " << st[cen].query(-1, in[u2][id2] - 1) << " " << out[u2][id2] << " " << st[cen].query(out[u2][id2] + 1, -1) << "\n"; //for(int i = 0; i < st[cen].sz; i++) cerr << st[cen].query(i, i) << " "; //cerr << "\n"; int ti = in[u2][id2], to = out[u2][id2]; if(ti <= in[v][i] && out[v][i] <= to) break; ans = min({ans, dpt[v][i] + st[cen].query(-1, ti - 1), dpt[v][i] + st[cen].query(to + 1, -1)}); break; } if(ans == MAX) cout << "oo\n"; else cout << ans << "\n"; } int main(){ StarBurstStream int q, s; cin >> n >> s >> q >> esc; init(); for(int i = 1; i < n; i++){ int u, v, w; cin >> u >> v >> w; g[u].eb(mp(v, w)); g[v].eb(mp(u, w)); e[i] = mp(u, v); } for(int i = 0; i < s; i++){ int c; cin >> c; shop[c] = true; } solve(1); //cerr << "test\n"; /*for(int i = 1; i <= n; i++){ cerr << i << " "; printv(pr[i], cerr); }*/ for(int i = 0; i < q; i++){ int eid, v; cin >> eid >> v; int u1 = e[eid].F, u2 = e[eid].S; query(u1, u2, v); } 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...