Submission #1270690

#TimeUsernameProblemLanguageResultExecution timeMemory
1270690thuhienneValley (BOI19_valley)C++20
36 / 100
3095 ms168864 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const int LOG = 17; const int can = 350; int n,q,numshop,root; int shop[100009]; vector <pair <int,int>> adj[100009]; struct { int u,v,w; } edge[100009]; int h[100009]; long long depth[100009]; int tin[100009],tout[100009],timedfs; int pos[100009],timelca,R[200009][LOG + 1]; void dfs(int node,int par) { tin[node] = ++timedfs; pos[node] = ++timelca; R[timelca][0] = node; for (auto x : adj[node]) if (x.first != par) { int ver = x.first,w = x.second; h[ver] = h[node] + 1; depth[ver] = depth[node] + w; dfs(ver,node); R[++timelca][0] = node; } tout[node] = timedfs; } bool intree(int child,int anc) { return tin[anc] <= tin[child] && tout[child] <= tout[anc]; } void buildsparse() { for (int j = 1;j <= LOG;j++) { for (int i = 1;i + (1 << j) - 1 <= timelca;i++) { int d1 = R[i][j - 1],d2 = R[i + (1 << (j - 1))][j - 1]; R[i][j] = (h[d1] < h[d2] ? d1 : d2); } } } int lca(int u,int v) { u = pos[u],v = pos[v]; if (u > v) swap(u,v); int i = __lg(v - u + 1); int d1 = R[u][i],d2 = R[v - (1 << i) + 1][i]; return (h[d1] < h[d2] ? d1 : d2); } long long dis(int u,int v) { return depth[u] + depth[v] - 2*depth[lca(u,v)]; } struct { int l,r; long long mindis[100009]; } block[can + 1]; void djt(vector <int> start,long long l[]) { for (int i = 1;i <= n;i++) l[i] = 1e18; priority_queue <pair<ll,int>,vector <pair <ll,int>>,greater <pair <ll,int>>> pq; for (auto x : start) { l[x] = 0; pq.push({l[x],x}); } while (pq.size()) { int ver = pq.top().second; long long cost = pq.top().first; pq.pop(); if (l[ver] < cost) continue; for (auto x : adj[ver]) { int u = x.first,w = x.second; if (l[u] > l[ver] + w) { l[u] = l[ver] + w; pq.push({l[u],u}); } } } } void precal() { sort(shop + 1,shop + 1 + numshop,[] (int a,int b) { return tin[a] < tin[b]; }); for (int id = 0;;id++) { block[id].l = max(1,id*can); block[id].r = min(numshop,(id + 1)*can - 1); vector <int> start; for (int i = block[id].l;i <= block[id].r;i++) start.push_back(shop[i]); djt(start,block[id].mindis); if (block[id].r == numshop) break; } } long long calc(int l,int r,int vertice) { if (l > r) return 1e18; long long ret = 1e18; int lid = l/can,rid = r/can; if (lid == rid) { for (int i = l;i <= r;i++) ret = min(ret,dis(vertice,shop[i])); return ret; } for (int i = l;i <= block[lid].r;i++) ret = min(ret,dis(vertice,shop[i])); for (int i = lid + 1;i < rid;i++) ret = min(ret,block[i].mindis[vertice]); for (int i = block[rid].l;i <= r;i++) ret = min(ret,dis(vertice,shop[i])); return ret; } int main() { ios_base::sync_with_stdio(0); cin.tie(nullptr); // freopen(".inp","r",stdin); // freopen(".out","w",stdout); cin >> n >> numshop >> q >> root; for (int i = 1;i < n;i++) { int u,v,w;cin >> u >> v >> w; adj[u].push_back({v,w}); adj[v].push_back({u,w}); edge[i] = {u,v,w}; } for (int i = 1;i <= numshop;i++) { cin >> shop[i]; } dfs(root,-1); buildsparse(); for (int i = 1;i < n;i++) if (h[edge[i].u] > h[edge[i].v]) swap(edge[i].u,edge[i].v); precal(); while (q--) { int vertice,_;cin >> _ >> vertice; int child = edge[_].v; //check escape if ((intree(vertice,child) ^ intree(root,child)) == 0) { cout << "escaped\n"; continue; } //tim khong trong shop ma cay con goc child quan ly int l,r; int low = 1,high = numshop; while (low <= high) { int mid = (low + high) >> 1; if (tin[shop[mid]] >= tin[child]) high = mid - 1; else low = mid + 1; } l = low; low = 1,high = numshop; while (low <= high) { int mid = (low + high) >> 1; if (tin[shop[mid]] <= tout[child]) low = mid + 1; else high = mid - 1; } r = high; long long ret = 1e18; //TH1: vertice nam trong cay con goc child if (intree(vertice,child)) { ret = calc(l,r,vertice); } //TH2: vertice khong nam trong cay con goc v else { ret = min(calc(1,l - 1,vertice),calc(r + 1,n,vertice)); } if (ret == 1e18) cout << "oo\n"; else cout << ret << '\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...