제출 #1289780

#제출 시각아이디문제언어결과실행 시간메모리
1289780i_love_kim_ji_wonEvacuation plan (IZhO18_plan)C++20
0 / 100
115 ms45508 KiB
// I ♡ 김지원 // #pragma GCC optimize("Ofast") // #pragma GCC target("avx,avx2,fma") #include <bits/stdc++.h> using namespace std; using ll = long long; const int N = 100000 + 5; const int LG = 20; const ll LINF = (ll)4e18; struct Edge { int v; ll w; }; struct Edge3 { int u, v; ll w; }; vector<Edge> g[N]; // reused: first original graph, later MST adjacency int U[200000 + 5], V[200000 + 5]; ll Worig[200000 + 5]; ll distArr[N]; struct Node { int u; ll d; bool operator<(Node const& other) const { return d > other.d; } }; // DSU int dsu_par[N], dsu_sz[N]; int find_set(int x){ return dsu_par[x]==x?x:dsu_par[x]=find_set(dsu_par[x]); } bool unite_set(int a,int b){ a = find_set(a); b = find_set(b); if (a == b) return false; if (dsu_sz[a] < dsu_sz[b]) swap(a,b); dsu_par[b] = a; dsu_sz[a] += dsu_sz[b]; return true; } // LCA tables int up[N][LG]; int depthArr[N]; ll mn[N][LG]; // mn[v][k] = min edge on path from v up to up[v][k] // Multi-source Dijkstra void multi_dijkstra(int n, const vector<int>& plants){ // distArr assumed initialized to LINF outside priority_queue<Node> pq; for (int p : plants) pq.push({p, 0}); while(!pq.empty()){ auto cur = pq.top(); pq.pop(); if (cur.d != distArr[cur.u]) continue; int u = cur.u; for (auto &e : g[u]){ int v = e.v; ll w = e.w; if (distArr[v] > distArr[u] + w){ distArr[v] = distArr[u] + w; pq.push({v, distArr[v]}); } } } } // Build MST adjacency (by cap) then compute parent/depth/mn via BFS (iterative) void build_lca_bfs(int n, int root){ // visited array vector<char> vis(n+1, 0); queue<int> q; q.push(root); vis[root] = 1; depthArr[root] = 0; up[root][0] = 0; mn[root][0] = LINF; // initialize others already done before while(!q.empty()){ int u = q.front(); q.pop(); for (auto &e : g[u]){ int v = e.v; ll w = e.w; if (vis[v]) continue; vis[v] = 1; depthArr[v] = depthArr[u] + 1; up[v][0] = u; mn[v][0] = w; // fill higher jumps for v for (int k = 1; k < LG; ++k){ up[v][k] = up[ up[v][k-1] ][k-1]; mn[v][k] = min(mn[v][k-1], mn[ up[v][k-1] ][k-1]); } q.push(v); } } // There might be multiple components (if MST didn't connect all) -> do BFS from any unvisited nodes for (int i = 1; i <= n; ++i){ if (!vis[i]){ vis[i] = 1; depthArr[i] = 0; up[i][0] = 0; mn[i][0] = LINF; for (int k = 1; k < LG; ++k){ up[i][k]=0; mn[i][k]=LINF; } q.push(i); while(!q.empty()){ int u2 = q.front(); q.pop(); for (auto &e : g[u2]){ int v = e.v; ll w = e.w; if (vis[v]) continue; vis[v] = 1; depthArr[v] = depthArr[u2] + 1; up[v][0] = u2; mn[v][0] = w; for (int k = 1; k < LG; ++k){ up[v][k] = up[ up[v][k-1] ][k-1]; mn[v][k] = min(mn[v][k-1], mn[ up[v][k-1] ][k-1]); } q.push(v); } } } } } int lca(int a, int b){ if (a == b) return a; if (depthArr[a] < depthArr[b]) swap(a,b); int diff = depthArr[a] - depthArr[b]; for (int i = 0; i < LG; ++i) if (diff >> i & 1) a = up[a][i]; if (a == b) return a; for (int i = LG-1; i >= 0; --i){ if (up[a][i] != up[b][i]){ a = up[a][i]; b = up[b][i]; } } return up[a][0]; } ll jump_min(int u, int anc){ if (u == anc) return LINF; ll res = LINF; int diff = depthArr[u] - depthArr[anc]; for (int i = 0; i < LG; ++i){ if (diff >> i & 1){ res = min(res, mn[u][i]); u = up[u][i]; } } return res; } ll query_path(int a, int b){ if (a == b) return 0; if (find_set(a) != find_set(b)) return 0; // not connected in MST -> no path int L = lca(a,b); ll la = jump_min(a, L); ll lb = jump_min(b, L); ll ans = min(la, lb); if (ans == LINF) return 0; return ans; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n,m; if (!(cin >> n >> m)) return 0; // clear for (int i = 1; i <= n; ++i){ g[i].clear(); distArr[i] = LINF; dsu_par[i] = i; dsu_sz[i] = 1; depthArr[i] = 0; for (int k = 0; k < LG; ++k){ up[i][k] = 0; mn[i][k] = LINF; } } for (int i = 1; i <= m; ++i){ int a,b; ll w; cin >> a >> b >> w; U[i] = a; V[i] = b; Worig[i] = w; g[a].push_back({b,w}); g[b].push_back({a,w}); } int k; cin >> k; vector<int> plants; plants.reserve(k); for (int i = 0; i < k; ++i){ int x; cin >> x; plants.push_back(x); distArr[x] = 0; } // run multi-source dijkstra multi_dijkstra(n, plants); // build edges with cap = min(dist[u], dist[v]) vector<Edge3> edges; edges.reserve(m); for (int i = 1; i <= m; ++i){ ll cap = min(distArr[U[i]], distArr[V[i]]); edges.push_back({U[i], V[i], cap}); } sort(edges.begin(), edges.end(), [](const Edge3 &a, const Edge3 &b){ return a.w > b.w; }); // clear adjacency to build MST for (int i = 1; i <= n; ++i) g[i].clear(); int root = 1; for (auto &e : edges){ if (unite_set(e.u, e.v)){ continue; // already same component -> skip } // merged -> add to MST g[e.u].push_back({e.v, e.w}); g[e.v].push_back({e.u, e.w}); root = e.u; } // prepare LCA with BFS (iterative). Fill up[][] and mn[][] build_lca_bfs(n, root); int Q; cin >> Q; while (Q--){ int s,t; cin >> s >> t; cout << query_path(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...