제출 #1291597

#제출 시각아이디문제언어결과실행 시간메모리
1291597hahaEvacuation plan (IZhO18_plan)C++20
100 / 100
297 ms58364 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll INF = (1LL << 60); const int MAXN = 100000; int n, m; vector<pair<int,int>> adj[MAXN+5]; // (neighbor, weight) ll dist_npp[MAXN+5]; struct Edge { int u, v; ll w; }; vector<Edge> edges; // DSU int parent[MAXN+5], sz[MAXN+5]; int find_set(int v){ if(v == parent[v]) return v; return parent[v] = find_set(parent[v]); } bool union_set(int a, int b){ a = find_set(a); b = find_set(b); if(a == b) return false; if(sz[a] < sz[b]) swap(a, b); parent[b] = a; sz[a] += sz[b]; return true; } vector<pair<int,ll>> mst[MAXN+5]; int up[MAXN+5][20]; ll mn[MAXN+5][20]; int depth[MAXN+5]; 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_set(u) != find_set(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; } 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}); } int k; cin >> k; vector<int> sources(k); for(int i = 0; i < k; i++) cin >> sources[i]; // Multi-source Dijkstra fill(dist_npp, dist_npp+n+1, INF); priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<pair<ll,int>>> pq; for(int g : sources){ dist_npp[g] = 0; pq.push({0, g}); } while(!pq.empty()){ auto [d, u] = pq.top(); pq.pop(); if(d != dist_npp[u]) continue; for(auto [v, w] : adj[u]){ if(dist_npp[v] > d + w){ dist_npp[v] = d + w; pq.push({dist_npp[v], v}); } } } // Build edges with weights = min(dist[u], dist[v]) for(int u = 1; u <= n; u++){ for(auto [v, w] : adj[u]){ if(u < v){ edges.push_back({u, v, min(dist_npp[u], dist_npp[v])}); } } } // Sort edges decreasing sort(edges.begin(), edges.end(), [](Edge &a, Edge &b){ return a.w > b.w; }); // Init DSU for(int i = 1; i <= n; i++){ parent[i] = i; sz[i] = 1; } // Build Maximum Spanning Tree for(auto &e : edges){ if(union_set(e.u, e.v)){ mst[e.u].push_back({e.v, e.w}); mst[e.v].push_back({e.u, e.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 for(int i = 1; i <= n; i++){ if(depth[i] == 0){ depth[i] = 1; dfs(i, 0); } } // 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...