Submission #1292000

#TimeUsernameProblemLanguageResultExecution timeMemory
1292000hahaEvacuation plan (IZhO18_plan)C++20
100 / 100
575 ms65852 KiB
#include <bits/stdc++.h> #define f first #define s second using namespace std; using ll = long long; const ll INF = (1LL << 60); const int MAXN = 100000+5; int n, m; vector<pair<int,int>> adj[MAXN+5]; // (neighbor, weight) priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>> Q; ll dis[MAXN]; int sources[MAXN],dsu[MAXN]; int k; struct Edge { int u, v; ll w; }; vector<Edge> edges; vector<pair<int,ll>> mst[MAXN+5]; int up[MAXN+5][20]; ll mn[MAXN+5][20]; int depth[MAXN+5]; int Find(int u) { if(u==dsu[u]) return u; int p=Find(dsu[u]); dsu[u]=p; return p; } bool join(int u,int v) { u=Find(u); v=Find(v); if(u==v) return false; dsu[u]=v; return true; } void dfs(int v, int p){ for(auto [to, w] : mst[v]){ if(to == p) continue; depth[to] = depth[v] + 1; up[to][0] = v; mn[to][0] = w; dfs(to, v); } } ll query(int u, int v){ if(Find(u) != Find(v)) return 0; ll res = INF; if(depth[u] < depth[v]) swap(u, v); // lift u up int diff = depth[u] - depth[v]; for(int k = 19; k >= 0; k--){ if(diff & (1<<k)){ res = min(res, mn[u][k]); u = up[u][k]; } } if(u == v) return res; for(int k = 19; k >= 0; k--){ if(up[u][k] != up[v][k]){ res = min(res, mn[u][k]); res = min(res, mn[v][k]); u = up[u][k]; v = up[v][k]; } } res = min(res, mn[u][0]); res = min(res, mn[v][0]); return res; } void dijkstra() { for(int i=1;i<=n;i++) dis[i]=1e18; for(int i=0;i<k;i++){ dis[sources[i]]=0; Q.push({0,sources[i]}); } while(!Q.empty()){ int u=Q.top().s; Q.pop(); for(int i=0;i<adj[u].size();i++){ int v=adj[u][i].f; int w=adj[u][i].s; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; Q.push({dis[v],v}); } } } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; for(int i = 1; i <= m; i++){ int a, b, w; cin >> a >> b >> w; adj[a].push_back({b, w}); adj[b].push_back({a, w}); } cin >> k; for(int i = 0; i < k; i++) cin >> sources[i]; dijkstra(); // Build edges with weights = min(dist[u], dist[v]) for(int i=1;i<=n;i++) dsu[i]=i; for(int u=1;u<=n;u++){ for(int i=0;i<adj[u].size();i++){ int v=adj[u][i].f; edges.push_back({u,v,min(dis[u],dis[v])}); } } sort(edges.begin(),edges.end(),[](Edge a, Edge b){ return a.w>b.w; }); for(int i = 1; i <= n; i++){ dsu[i]=i; } // Build Maximum Spanning Tree for(int i=0;i<edges.size();i++){ int u=edges[i].u; int v=edges[i].v; if(join(u,v)){ mst[u].push_back({v,edges[i].w}); mst[v].push_back({u,edges[i].w}); } } // LCA preprocess for(int i = 1; i <= n; i++){ for(int k = 0; k < 20; k++){ up[i][k] = 0; mn[i][k] = INF; } } // DFS from all components dfs(1,1); // Build binary lifting for(int k = 1; k < 20; k++){ for(int v = 1; v <= n; v++){ int mid = up[v][k-1]; up[v][k] = up[mid][k-1]; mn[v][k] = min(mn[v][k-1], mn[mid][k-1]); } } // Answer queries int Q; cin >> Q; while(Q--){ int s, t; cin >> s >> t; cout << query(s, t) << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...