Submission #1096291

#TimeUsernameProblemLanguageResultExecution timeMemory
1096291TrinhKhanhDungValley (BOI19_valley)C++14
100 / 100
248 ms26520 KiB
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define sz(x) (int)x.size() #define ALL(v) v.begin(),v.end() #define MASK(k) (1LL << (k)) #define BIT(x, i) (((x) >> (i)) & 1) #define oo (ll)1e18 #define INF (ll)1e9 #define MOD (ll)(1e9 + 7) using namespace std; template<class T1, class T2> bool maximize(T1 &a, T2 b){if(a < b){a = b; return true;} return false;} template<class T1, class T2> bool minimize(T1 &a, T2 b){if(a > b){a = b; return true;} return false;} template<class T1, class T2> void add(T1 &a, T2 b){a += b; if(a >= MOD) a -= MOD;} template<class T1, class T2> void sub(T1 &a, T2 b){a -= b; if(a < 0) a += MOD;} template<class T> void cps(T &v){sort(ALL(v)); v.resize(unique(ALL(v)) - v.begin());} struct seg{ vector<ll> val, laz; int n; seg(int _n = 0){ n = _n; val.resize(4 * n + 3, 0); laz.resize(4 * n + 3, 0); } void push(int i){ ll t = laz[i]; if(t == 0) return; laz[i] = 0; laz[i * 2] += t; laz[i * 2 + 1] += t; val[i * 2] += t; val[i * 2 + 1] += t; } void upd(int i, int l, int r, int u, int v, ll c){ if(r < u || v < l) return; if(u <= l && r <= v){ laz[i] += c; val[i] += c; return; } push(i); int m = (l + r) >> 1; upd(i * 2, l, m, u, v, c); upd(i * 2 + 1, m + 1, r, u, v, c); val[i] = min(val[i * 2], val[i * 2 + 1]); } ll get(int i, int l, int r, int u, int v){ if(r < u || v < l) return oo; if(u <= l && r <= v) return val[i]; push(i); int m = (l + r) >> 1; return min(get(i * 2, l, m, u, v), get(i * 2 + 1, m + 1, r, u, v)); } } it; const int maxN = 1e5 + 10; int N, M, Q, S; vector<pair<int, int>> adj[maxN]; array<int, 3> edges[maxN]; int timer, nChain = 1; int nChild[maxN], chain[maxN], topNode[maxN], par[maxN], in[maxN], out[maxN]; ll dist[maxN], ans[maxN]; vector<pair<int, int>> queries[maxN]; void countChild(int u, int p = -1){ par[u] = p; nChild[u] = 1; for(auto o: adj[u]){ int v = o.fi; int id = o.se; if(v == p) continue; countChild(v, u); nChild[u] += nChild[v]; if(edges[id][0] == v) swap(edges[id][0], edges[id][1]); } } void hld(int u){ if(topNode[nChain] == 0) topNode[nChain] = u; chain[u] = nChain; in[u] = ++timer; int heavyNode = -1; for(auto o: adj[u]){ int v = o.fi; if(v == par[u]) continue; if(heavyNode == -1 || nChild[heavyNode] < nChild[v]){ heavyNode = v; } } if(heavyNode != -1){ hld(heavyNode); } for(auto o: adj[u]){ int v = o.fi; if(v == par[u] || v == heavyNode) continue; nChain++; hld(v); } out[u] = timer; } void update(int a, int u, ll c){ while(true){ if(chain[u] == chain[a]){ it.upd(1, 1, N, in[a], in[u], c); break; } int p = topNode[chain[u]]; it.upd(1, 1, N, in[p], in[u], c); u = par[p]; } } ll query(int a, int u){ ll ans = oo; while(true){ if(chain[u] == chain[a]){ minimize(ans, it.get(1, 1, N, in[a], in[u])); break; } int p = topNode[chain[u]]; minimize(ans, it.get(1, 1, N, in[p], in[u])); u = par[p]; } return ans; } void calc(int u){ for(auto o: queries[u]){ int x = o.fi, id = o.se; // cout << u << ' ' << x << ' ' << o.se << '\n'; if(!(in[x] <= in[u] && out[u] <= out[x])){ ans[id] = -1; continue; } else{ ans[id] = query(x, u); } } for(auto o: adj[u]){ int v = o.fi; ll c = edges[o.se][2]; if(v == par[u]) continue; update(S, u, c); calc(v); update(S, u, -c); } } void dfs(int u, int p = -1){ for(auto o: adj[u]){ int v = o.fi; ll c = edges[o.se][2]; if(v == p) continue; dfs(v, u); minimize(dist[u], dist[v] + c); } } void solve(){ cin >> N >> M >> Q >> S; for(int i = 1; i < N; i++){ int u, v, c; cin >> u >> v >> c; adj[u].push_back({v, i}); adj[v].push_back({u, i}); edges[i] = {u, v, c}; } memset(dist, 0x3f, sizeof dist); for(int i = 1; i <= M; i++){ int x; cin >> x; dist[x] = 0; } countChild(S); hld(S); dfs(S); for(int i = 1; i <= Q; i++){ int x, y; cin >> x >> y; x = edges[x][1]; queries[y].push_back({x, i}); } it = seg(N); // for(int i = 1; i < N; i++){ // cout << edges[i][0] << ' ' << edges[i][1] << '\n'; // } for(int i = 1; i <= N; i++){ it.upd(1, 1, N, in[i], in[i], dist[i]); } calc(S); for(int i = 1; i <= Q; i++){ if(ans[i] == -1){ cout << "escaped\n"; } else if(ans[i] >= oo){ cout << "oo\n"; } else{ cout << ans[i] << '\n'; } } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); // freopen("capsomayman.inp","r",stdin); // freopen("capsomayman.out","w",stdout); int t = 1; // cin >> t; while(t--){ solve(); } 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...