제출 #1277316

#제출 시각아이디문제언어결과실행 시간메모리
1277316_filya_Valley (BOI19_valley)C++20
100 / 100
184 ms69128 KiB
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int N = 1e5 + 50, lgN = 22; ll par[N], lifting1[N][lgN], lifting2[N][lgN], lifting3[N][lgN], nv[N], shop[N], depth[N], inf = 1e18; int n, s, q, e; vector<pair<int, ll>> G[N]; void dfs(int s, int p, ll w) { par[s] = p; depth[s] = depth[p] + 1; lifting2[s][0] = w; nv[s] = (shop[s] ? 0 : inf); for (auto u : G[s]) { if (u.first == p) continue; dfs(u.first, s, u.second); nv[s] = min(nv[s], nv[u.first] + u.second); } } int kth_parent(int node, int k) { if (k > n) { return -1; } int at = node; for (int pow = 0; pow <= lgN; pow++) { if ((k & (1 << pow)) != 0) { at = lifting1[at][pow]; if (at == -1) { break; } } } return at; } int lca(int n1, int n2) { if (depth[n1] < depth[n2]) { return lca(n2, n1); } n1 = kth_parent(n1, depth[n1] - depth[n2]); if (n1 == n2) { return n2; } for (int i = lgN; i >= 0; i--) { if (lifting1[n1][i] != lifting1[n2][i]) { n1 = lifting1[n1][i]; n2 = lifting1[n2][i]; } } return lifting1[n1][0]; } int main() { // ifstream cin("input.txt"); // ofstream cout("output.txt"); ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n >> s >> q >> e; vector<pair<int, int>> edges; for (int i = 0; i < n - 1; i++) { int a, b, w; cin >> a >> b >> w; G[a].push_back({b, w}); G[b].push_back({a, w}); edges.push_back({a, b}); } while(s--) { int c; cin >> c; shop[c] = 1; } dfs(e, e, 0); for (auto& [a, b] : edges) { if (depth[a] < depth[b]) swap(a, b); } for (int i = 1; i <= n; i++) { lifting1[i][0] = par[i]; lifting3[i][0] = min(nv[i], nv[par[i]] + lifting2[i][0]); } for (int lg = 1; lg < lgN; lg++) { for (int i = 1; i <= n; i++) { lifting1[i][lg] = lifting1[lifting1[i][lg - 1]][lg - 1]; lifting2[i][lg] = lifting2[lifting1[i][lg - 1]][lg - 1] + lifting2[i][lg - 1]; lifting3[i][lg] = min(lifting3[i][lg - 1], lifting3[lifting1[i][lg - 1]][lg - 1] + lifting2[i][lg - 1]); } } while(q--) { int i, r; cin >> i >> r; int u = edges[i - 1].first; if (lca(u, r) == u) { int w = depth[r] - depth[u]; ll res = nv[r], curdist = 0; for (int lg = 0; lg < lgN; lg++) { if (w % 2) { res = min(res, lifting3[r][lg] + curdist); curdist += lifting2[r][lg]; r = lifting1[r][lg]; } w /= 2; } if (res >= inf) cout << "oo\n"; else cout << res << '\n'; } else { cout << "escaped\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...