제출 #702422

#제출 시각아이디문제언어결과실행 시간메모리
702422Zian_JacobsonValley (BOI19_valley)C++17
100 / 100
618 ms97852 KiB
#include<bits/stdc++.h> using namespace std; #define cIO ios_base::sync_with_stdio(0);cin.tie(0) #define fileIO(x) ifstream fin(string(x)+".in"); ofstream fout(string(x)+".out") #define cont(container, object) (container.find(object)!=container.end()) #define sz(x) (int) (x).size() #define ll long long #define v vector const ll INF = LLONG_MAX / 2; const int max_log = 18; v<v<pair<int, ll>>> adj; v<pair<int, ll>> p; v<v<pair<int, ll>>> c; v<v<pair<int, ll>>> jmp; v<v<ll>> jmp_f, jmp_d;//jump 2^k steps to parent & distance v<ll> ds_subtree;//min dist to store in subtree v<bool> is_store; v<int> depth; v<pair<int, int>> roads_list; void dfs_p(int node) { if (is_store[node]) ds_subtree[node] = 0; for (auto nxt : adj[node]) if (nxt.first != p[node].first) { p[nxt.first] = { node, nxt.second }; c[node].push_back(nxt); depth[nxt.first] = depth[node] + 1; dfs_p(nxt.first); ds_subtree[node] = min(ds_subtree[node], ds_subtree[nxt.first]+nxt.second); } return; } int main() { fileIO("valley"); //remember distances could be long long int N, S, Q, E; cin >> N >> S >> Q >> E; adj.resize(N + 1); is_store.resize(N + 1); p.resize(N + 1); c.resize(N + 1); p[E] = { E,0 }; ds_subtree.resize(N + 1, INF); depth.resize(N + 1); jmp = v<v<pair<int, ll>>>(N + 1, v<pair<int, ll>>(max_log + 1)); jmp_f = jmp_d = v<v<ll>>(N + 1, v<ll>(max_log + 1, INF)); roads_list.resize(N + 1); for (int i = 1; i <= N - 1; i++) { int a, b; ll c; cin >> a >> b >> c; adj[a].push_back({ b,c }); adj[b].push_back({ a,c }); roads_list[i] = { a,b }; } for (int i = 1; i <= S; i++) { int a; cin >> a; is_store[a] = true; } dfs_p(E); for (int i = 1; i <= N; i++) { jmp[i][0] = p[i]; } for (int dep = 1; dep <= max_log; dep++) for (int i = 1; i <= N; i++) { jmp[i][dep] = { jmp[jmp[i][dep - 1].first][dep - 1].first, jmp[i][dep - 1].second + jmp[jmp[i][dep - 1].first][dep - 1].second }; } for (int i = 1; i <= N; i++) { jmp_d[i][0] = jmp[i][0].second + ds_subtree[jmp[i][0].first]; } for (int dep = 1; dep <= max_log; dep++) for (int i=1; i <= N; i++) { jmp_d[i][dep] = min(jmp_d[i][dep - 1], jmp_d[jmp[i][dep - 1].first][dep - 1] + jmp[i][dep - 1].second); } for (int z = 1; z <= Q; z++) { int I, R; cin >> I >> R; pair<int, int> rem = roads_list[I]; if (depth[rem.first] > depth[rem.second]) swap(rem.first, rem.second); int top_node = rem.second; //first check if top_node is not a parent of R if (depth[R] < depth[top_node]) { cout << "escaped\n"; continue; } int stp = depth[R] - depth[top_node]; int R1 = R; for (int i = 0; i <= max_log; i++) { if (stp & (1 << i)) R1 = jmp[R1][i].first; } if (R1!=top_node) { cout << "escaped\n"; continue; } //we know that top_node is a parent ll min_cost = ds_subtree[R]; ll cum_jmp_cost = 0; R1 = R; for (int i = 0; i <= max_log; i++) { if (stp & (1 << i)) { min_cost = min(min_cost, jmp_d[R1][i] + cum_jmp_cost); cum_jmp_cost += jmp[R1][i].second; R1 = jmp[R1][i].first; } } if (min_cost == INF) cout << "oo\n"; else cout << min_cost << "\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...