제출 #1128673

#제출 시각아이디문제언어결과실행 시간메모리
1128673_callmelucianEvacuation plan (IZhO18_plan)C++17
100 / 100
465 ms42256 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef pair<ll,ll> pl; typedef pair<int,int> pii; typedef tuple<int,int,int> tpl; #define all(a) a.begin(), a.end() #define filter(a) a.erase(unique(all(a)), a.end()) const int mn = 1e5 + 5; vector<pl> adj[mn]; ll dist[mn], n; bool vis[mn]; void dijkstra (const vector<int> &sources) { for (int i = 1; i <= n; i++) dist[i] = LLONG_MAX, vis[i] = 0; priority_queue<pl> pq; for (int u : sources) dist[u] = 0, pq.emplace(0, u); while (pq.size()) { int u = pq.top().second; pq.pop(); if (vis[u]) continue; vis[u] = 1; for (pl item : adj[u]) { ll v, w; tie(v, w) = item; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.emplace(-dist[v], v); } } } } namespace tree { int spt[mn][17], par[mn], chain[mn], sz[mn], depth[mn], num[mn], timeDfs; vector<int> adj[mn]; int szDfs (int u, int p) { sz[u] = 1; for (int v : adj[u]) if (v != p) sz[u] += szDfs(v, u); return sz[u]; } void dfs (int u, int p, int d, bool toP) { if (u == 1) szDfs(u, p); num[u] = ++timeDfs, par[u] = p, depth[u] = d; chain[u] = (toP ? chain[p] : u); sort(all(adj[u]), [&] (int a, int b) { return sz[a] > sz[b]; }); bool heavy = 1; for (int v : adj[u]) if (v != p) dfs(v, u, d + 1, heavy), heavy = 0; } int rmq (int l, int r) { int p = 31 - __builtin_clz(r - l + 1); return min(spt[l][p], spt[r - (1 << p) + 1][p]); } int query (int a, int b) { int ans = INT_MAX; while (chain[a] != chain[b]) { int ap = par[chain[a]], bp = par[chain[b]]; if (depth[ap] == depth[bp]) { ans = min(ans, rmq(num[chain[a]], num[a])), a = ap; ans = min(ans, rmq(num[chain[b]], num[b])), b = bp; } else if (depth[ap] > depth[bp]) ans = min(ans, rmq(num[chain[a]], num[a])), a = ap; else if (depth[bp] > depth[ap]) ans = min(ans, rmq(num[chain[b]], num[b])), b = bp; } if (depth[a] > depth[b]) swap(a, b); return min(ans, rmq(num[a], num[b])); } void process() { dfs(1, 0, 1, 0); for (int i = 1; i <= n; i++) spt[num[i]][0] = dist[i]; for (int s = 1; (1 << s) <= n; s++) { for (int i = 1; i + (1 << s) - 1 <= n; i++) { int p = s - 1; spt[i][s] = min(spt[i][p], spt[i + (1 << p)][p]); } } } void addEdge (int a, int b) { adj[a].push_back(b); adj[b].push_back(a); } }; struct DSU { vector<int> lab; DSU (int sz) : lab(sz + 1, -1) {} int get (int u) { if (lab[u] < 0) return u; return lab[u] = get(lab[u]); } bool unite (int a, int b) { a = get(a), b = get(b); if (a == b) return 0; if (-lab[a] < -lab[b]) swap(a, b); lab[a] += lab[b], lab[b] = a; return 1; } }; int main() { ios::sync_with_stdio(0); cin.tie(0); int m; cin >> n >> m; for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; adj[a].emplace_back(b, c); adj[b].emplace_back(a, c); } int k; cin >> k; vector<int> sources(k), ord(n); for (int &u : sources) cin >> u; dijkstra(sources); for (int i = 1; i <= n; i++) ord[i - 1] = i; sort(all(ord), [&] (int a, int b) { return dist[a] > dist[b]; }); vector<bool> added(n + 1); DSU dsu(n); for (int u : ord) { added[u] = 1; for (pl item : adj[u]) { int v = item.first; if (added[v] && dsu.unite(u, v)) tree::addEdge(u, v); } } tree::process(); int q; cin >> q; while (q--) { int u, v; cin >> u >> v; cout << tree::query(u, v) << "\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...