Submission #492372

#TimeUsernameProblemLanguageResultExecution timeMemory
492372socpiteEvacuation plan (IZhO18_plan)C++14
0 / 100
677 ms40928 KiB
#include<bits/stdc++.h> using namespace std; #define f first #define s second const int maxn = 100001; const int oo = 1e9+7; const int mx2 = 18; int st[2][mx2][maxn]; int n, m, k, q; void build(int x){ if(x == mx2)return; for(int i = 1; i <= n; i++){ if(st[0][x-1][i] != -1){ st[0][x][i] = st[0][x-1][st[0][x-1][i]]; st[1][x][i] = min(st[1][x-1][i], st[1][x-1][st[0][x-1][i]]); } else{ st[0][x][i]=-1; st[1][x][i]=-1; } } build(x+1); } vector<int> up; vector<vector<pair<int, int>>> graph; vector<vector<int>> tree; vector<int> level; vector<pair<int, int>> edges; vector<int> sp; vector<bool> locked; struct cmp{ bool operator()(pair<int, int> a, pair<int, int> b){ return a.f > b.f; } }; bool cmp2(pair<int, int> a, pair<int, int> b){ return min(sp[a.f], sp[a.s]) > min(sp[b.f], sp[b.s]); } int Find(int x){ if(up[x] < 0)return x; else{ up[x]=Find(up[x]); return up[x]; } } void Union(int a, int b){ a = Find(a); b = Find(b); up[b]=a; } void addedge(pair<int, int> x){ tree[x.f].push_back(x.s); tree[x.s].push_back(x.f); } int travelup(int &x, int dist){ int re = oo; if(dist == 0)return oo; else{ for(int i = 0; i < mx2; i++){ if(dist&(1 << i)){ re = min(re, st[1][i][x]); x = st[0][i][x]; } } } return re; } void DFS(int x, int p){ for(auto u: tree[x]){ if(u == p)continue; level[u]=level[x]+1; st[0][0][u]=x; st[1][0][u]=min(sp[x], sp[u]); DFS(u, x); } } int gtpath(int a, int b){ int ans = oo; if(level[a] > level[b])swap(a, b); ans = min(ans, travelup(b, level[b]-level[a])); if(a == b)return ans; for(int i = mx2-1; i >= 0; i--){ if(st[0][i][a] != st[0][i][b]){ ans = min(ans, st[1][i][a]); a = st[0][i][a]; ans = min(ans, st[1][i][b]); a = st[0][i][b]; } } return min(ans, sp[st[0][0][a]]); } priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq; int main(){ cin >> n >> m; sp.assign(n+1, oo); graph.resize(n+1); locked.assign(n+1, 0); level.assign(n+1, 0); up.assign(n+1, -1); st[0][0][1]=-1; for(int i = 0; i < m; i++){ int a, b, c; cin >> a >> b >> c; graph[a].push_back({b, c}); graph[b].push_back({a, c}); edges.push_back({a, b}); } cin >> k; for(int i = 0; i < k; i++){ int x; cin >> x; sp[x]=0; pq.push({0, x}); } while(!pq.empty()){ auto x = pq.top(); pq.pop(); if(locked[x.s])continue; locked[x.s]=true; for(auto u: graph[x.s]){ if(sp[u.f] > u.s+sp[x.s]){ sp[u.f] = u.s+sp[x.s]; pq.push({sp[u.f], u.f}); } } } tree.resize(n+1); sort(edges.begin(), edges.end(), cmp2); for(int i = 0; i < m; i++){ if(Find(edges[i].f) != Find(edges[i].s)){ Union(edges[i].f, edges[i].s); addedge(edges[i]); } } DFS(1, 0); build(1); cin >> q; for(int i = 0; i < q; i++){ int a, b; cin >> a >> b; cout << gtpath(a, b) << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...