Submission #290524

#TimeUsernameProblemLanguageResultExecution timeMemory
290524VROOM_VARUNValley (BOI19_valley)C++14
100 / 100
417 ms60720 KiB
/* ID: varunra2 LANG: C++ TASK: valley */ #include <bits/stdc++.h> using namespace std; #ifdef DEBUG #include "lib/debug.h" #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #define debug_arr(...) \ cerr << "[" << #__VA_ARGS__ << "]:", debug_arr(__VA_ARGS__) #pragma GCC diagnostic ignored "-Wsign-compare" //#pragma GCC diagnostic ignored "-Wunused-parameter" //#pragma GCC diagnostic ignored "-Wunused-variable" #else #define debug(...) 42 #endif #define EPS 1e-9 #define IN(A, B, C) assert(B <= A && A <= C) #define INF (ll)1e15 #define MEM(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define MP make_pair #define PB push_back #define all(cont) cont.begin(), cont.end() #define rall(cont) cont.end(), cont.begin() #define x first #define y second const double PI = acos(-1.0); typedef long long ll; typedef long double ld; typedef pair<ll, ll> PII; typedef map<int, int> MPII; typedef multiset<int> MSETI; typedef set<int> SETI; typedef set<string> SETS; typedef vector<ll> VI; typedef vector<PII> VII; typedef vector<VI> VVI; typedef vector<string> VS; #define rep(i, a, b) for (int i = a; i < (b); ++i) #define trav(a, x) for (auto& a : x) #define sz(x) (int)(x).size() typedef pair<int, int> pii; typedef vector<int> vi; #pragma GCC diagnostic ignored "-Wsign-compare" // util functions int n, s, e, q; vector<VII> adj; VI tin; VI tout; int curtime = 0; VI magic; VI dist; VVI parmq; VI cmin; vector<bool> shop; VII edg; VVI lca; const int segsize = 20; // change this when submitting // e is the root void init() { adj.resize(n); tin.resize(n); tout.resize(n); magic.resize(n); dist.resize(n); parmq.resize(n); cmin.resize(n); shop.resize(n); edg.resize(n - 1); lca.resize(n); for (int i = 0; i < n; i++) { parmq[i].resize(segsize); lca[i].resize(segsize); cmin[i] = INF; } } bool isAnc(int u, int v) { if (u == -1) return true; if (v == -1) return false; return tin[u] <= tin[v] and tout[u] >= tout[v]; } void dfs_lca(int u, int v) { lca[u][0] = v; tin[u] = ++curtime; for (int i = 1; i < segsize; i++) { int to = lca[u][i - 1]; if (to == -1) lca[u][i] = -1; else lca[u][i] = lca[to][i - 1]; } for (auto& x : adj[u]) { if (x.x == v) continue; dfs_lca(x.x, u); } tout[u] = ++curtime; } void dfs_dist(int u, int v) { for (auto& x : adj[u]) { if (x.x == v) continue; dist[x.x] = dist[u] + x.y; dfs_dist(x.x, u); } } void dfs_magic(int u, int v) { for (auto& x : adj[u]) { if (x.x == v) continue; dfs_magic(x.x, u); cmin[u] = min(cmin[u], cmin[x.x]); } if (shop[u]) cmin[u] = dist[u]; magic[u] = -2 * dist[u] + cmin[u]; } void dfs_build_parmq(int u, int v) { parmq[u][0] = magic[u]; for (int i = 1; i < segsize; i++) { int to = lca[u][i - 1]; if (to == -1) parmq[u][i] = parmq[u][i - 1]; else parmq[u][i] = min(parmq[u][i - 1], parmq[to][i - 1]); } for (auto& x : adj[u]) { if (x.x == v) continue; dfs_build_parmq(x.x, u); } } ll qry(int u, int v) { ll ret = INF; for (int i = segsize - 1; i >= 0; i--) { if (!isAnc(lca[u][i], v)) { ret = min(ret, parmq[u][i]); u = lca[u][i]; } } ret = min(ret, min(magic[v], magic[u])); return ret; } int main() { // #ifndef ONLINE_JUDGE // freopen("valley.in", "r", stdin); // freopen("valley.out", "w", stdout); // #endif cin.sync_with_stdio(0); cin.tie(0); cin >> n >> s >> q >> e; e--; init(); for (int i = 0; i < n - 1; i++) { int u, v, w; cin >> u >> v >> w; u--; v--; adj[u].PB(MP(v, w)); adj[v].PB(MP(u, w)); edg[i] = MP(u, v); } for (int i = 0; i < s; i++) { int c; cin >> c; c--; shop[c] = true; } dfs_lca(e, -1); // got in and out times of each node dfs_dist(e, -1); // got distances dfs_magic(e, -1); // made the magic array // now we need to calculate dfs_build_parmq(e, -1); // for(int i = 0; i < q; i++) { // } for (int i = 0; i < q; i++) { int ind, r; cin >> ind >> r; ind--; r--; int u, v; u = edg[ind].x; v = edg[ind].y; if (dist[u] < dist[v]) swap(u, v); if (!isAnc(u, r)) { cout << "escaped\n"; } else { ll ret = dist[r] + qry(r, u); if (shop[r]) ret = 0; if (ret <= INF / 10 + 1ll) cout << ret << '\n'; else cout << "oo" << '\n'; } } 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...