Submission #419984

#TimeUsernameProblemLanguageResultExecution timeMemory
419984nicolaalexandraValley (BOI19_valley)C++14
100 / 100
656 ms29204 KiB
#include <bits/stdc++.h> #define DIM 100010 #define INF 1000000000000000000LL using namespace std; struct segment_tree{ long long mini,lazy; } aint[DIM*4]; struct muchie{ int x,y,cost; } mch[DIM]; vector <pair<int,int> > L[DIM],v[DIM]; pair <int,int> poz[DIM]; int E[DIM],level[DIM],f[DIM]; long long dist[DIM],sol[DIM]; int n,m,q,e,i,j,x,y,cost,k; void dfs (int nod, int tata){ E[++k] = nod; poz[nod].first = k; level[nod] = 1 + level[tata]; for (auto it : L[nod]){ int vecin = it.first; if (vecin != tata){ dist[vecin] = dist[nod] + it.second; dfs (vecin,nod); } } poz[nod].second = k; } void build (int nod, int st, int dr){ if (st == dr){ if (f[E[st]]) aint[nod].mini = dist[E[st]]; else aint[nod].mini = INF; return; } int mid = (st+dr)>>1; build (nod<<1,st,mid); build ((nod<<1)|1,mid+1,dr); aint[nod].mini = min (aint[nod<<1].mini, aint[(nod<<1)|1].mini); } void update_lazy (int nod, int st, int dr){ if (!aint[nod].lazy) return; if (st != dr){ int fiu_st = nod<<1, fiu_dr = (nod<<1)|1; if (aint[fiu_st].mini != INF){ aint[fiu_st].mini += aint[nod].lazy; aint[fiu_st].lazy += aint[nod].lazy; } if (aint[fiu_dr].mini != INF){ aint[fiu_dr].mini += aint[nod].lazy; aint[fiu_dr].lazy += aint[nod].lazy; } } aint[nod].lazy = 0; } void update (int nod, int st, int dr, int x, int y, long long val){ if (x > y) return; update_lazy (nod,st,dr); if (x <= st && dr <= y){ if (aint[nod].mini != INF){ aint[nod].mini += val; aint[nod].lazy += val; update_lazy (nod,st,dr); } return; } int mid = (st+dr)>>1; if (x <= mid) update (nod<<1,st,mid,x,y,val); if (y > mid) update ((nod<<1)|1,mid+1,dr,x,y,val); update_lazy (nod<<1,st,mid); update_lazy ((nod<<1)|1,mid+1,dr); aint[nod].mini = min (aint[nod<<1].mini, aint[(nod<<1)|1].mini); } long long query (int nod, int st, int dr, int x, int y){ if (x > y) return INF; update_lazy (nod,st,dr); if (x <= st && dr <= y) return aint[nod].mini; int mid = (st+dr)>>1; long long sol_st = INF, sol_dr = INF; if (x <= mid) sol_st = query (nod<<1,st,mid,x,y); if (y > mid) sol_dr = query ((nod<<1)|1,mid+1,dr,x,y); return min (sol_st,sol_dr); } void dfs2 (int nod, int tata, int cost){ if (nod != 1){ update (1,1,n,1,poz[nod].first-1,cost); update (1,1,n,poz[nod].first,poz[nod].second,-cost); update (1,1,n,poz[nod].second+1,n,cost); } /// parcurg toate query-urile din nodul asta for (auto it : v[nod]){ int x = mch[it.first].x, y = mch[it.first].y; if (level[x] > level[y]) swap (x,y); long long val = INF; if (poz[nod].first >= poz[y].first && poz[nod].second <= poz[y].second){ /// x e stramos => iau in calcul doar subarborele lui y val = min (val,query(1,1,n,poz[y].first,poz[y].second)); } else { val = min (val,query(1,1,n,1,poz[y].first-1)); val = min (val,query(1,1,n,poz[y].second+1,n)); } sol[it.second] = val; } for (auto it : L[nod]){ int vecin = it.first; if (vecin != tata) dfs2 (vecin,nod,it.second); } if (nod != 1){ update (1,1,n,1,poz[nod].first-1,-cost); update (1,1,n,poz[nod].first,poz[nod].second,cost); update (1,1,n,poz[nod].second+1,n,-cost); } } int verif_exit (int idx, int nod){ int x = mch[idx].x, y = mch[idx].y, cnt = 0; if (level[x] > level[y]) swap (x,y); if (poz[nod].first >= poz[y].first && poz[nod].second <= poz[y].second) cnt++; if (poz[e].first >= poz[y].first && poz[e].second <= poz[y].second) cnt++; if (cnt == 1) return 0; return 1; } int main (){ //ifstream cin ("date.in"); //ofstream cout ("date.out"); cin>>n>>m>>q>>e; for (i=1;i<n;i++){ cin>>x>>y>>cost; mch[i] = {x,y,cost}; L[x].push_back(make_pair(y,cost)); L[y].push_back(make_pair(x,cost)); } for (i=1;i<=m;i++){ cin>>x; f[x] = 1; } dfs (1,0); build (1,1,n); for (i=1;i<=q;i++){ cin>>x>>y; if (!verif_exit(x,y)) v[y].push_back(make_pair(x,i)); else sol[i] = -1; } dfs2 (1,0,0); for (i=1;i<=q;i++){ if (sol[i] == -1) cout<<"escaped\n"; else { if (sol[i] == INF) cout<<"oo\n"; else cout<<sol[i]<<"\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...