Submission #784577

#TimeUsernameProblemLanguageResultExecution timeMemory
784577farukValley (BOI19_valley)C++17
100 / 100
249 ms66996 KiB
#include <bits/stdc++.h> #define mp make_pair #define all(a) a.begin(), a.end() using namespace std; typedef long long ll; typedef pair<ll, ll> pii; const int K = 20; struct info { ll length, min_cost, top_node; info() {length=0,min_cost=0;} info(ll a, ll b, ll c) {length = a, min_cost = b, top_node = c;} }; info merge(info lower, info higher) { return info(lower.length + higher.length, min(lower.min_cost, higher.min_cost + lower.length), higher.top_node); } vector<pair<pii, ll> > edges; vector<vector<pii> > graph; vector<vector<info> > lift; vector<int> in_time; vector<int> out_time; vector<bool> is_shop; int tim = 0; ll dfs(int curr, ll par, ll edge_cst) { ll min_cost = 1e18; if (is_shop[curr]) min_cost = 0; in_time[curr] = tim; for (auto &[a, w] : graph[curr]) { if (a == par) continue; tim++; min_cost = min(min_cost, dfs(a, curr, w) + w); } lift[0][curr] = info(edge_cst, min_cost, par); out_time[curr] = ++tim; return min_cost; } void dfs2(int curr, ll par) { for (int i = 1; i < K; i++) lift[i][curr] = merge(lift[i - 1][curr], lift[i-1][lift[i-1][curr].top_node]); for (auto &[a, w] : graph[curr]) if (a != par) dfs2(a, curr); } bool is_ancestor(int a, int b) { return in_time[a] <= in_time[b] and out_time[a] >= out_time[b]; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, s, q, e; cin >> n >> s >> q >> e; graph = vector<vector<pii> > (n+1); in_time.resize(n+1); in_time[0] = -1e9; out_time.resize(n+1); out_time[0] = 1e9; edges.resize(n+1); is_shop.resize(n+1); lift.resize(K, vector<info>(n+1)); for (int i = 0; i < n - 1; i++) { cin >> edges[i].first.first >> edges[i].first.second >> edges[i].second; graph[edges[i].first.first].push_back({edges[i].first.second, edges[i].second}); graph[edges[i].first.second].push_back({edges[i].first.first, edges[i].second}); } for (int i = 0; i < s; i++) { int guy; cin >> guy; is_shop[guy] = true; } dfs(e, 0, 0); dfs2(e, 0); while (q--) { int block, r; cin >> block >> r; block--; pii block_edge = edges[block].first; if (in_time[block_edge.first] < in_time[block_edge.second]) swap(block_edge.first, block_edge.second); int block_node = block_edge.first; // checking if you can leave if (!is_ancestor(block_node, r)) { cout << "escaped\n"; continue; } block_node = lift[0][block_edge.second].top_node; // now_bin_lifting info ans = lift[0][r]; for (int i = K - 1; i >= 0; i--) { info top = lift[i][ans.top_node]; if (is_ancestor(top.top_node, block_node)) continue; ans = merge(ans, top); } if (ans.min_cost >= 1e18) cout << "oo\n"; else cout << ans.min_cost << "\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...