Submission #1230723

#TimeUsernameProblemLanguageResultExecution timeMemory
1230723raphaeltfaFactories (JOI14_factories)C++20
100 / 100
1805 ms181100 KiB
#include <bits/stdc++.h> using namespace std; const long long inf = 1e18; int n, timer; vector<vector<pair<int, long long>>> adj; vector<vector<int>> up; vector<long long> dist; vector<int> in_time, out_time; vector<vector<int>> vt_adj; vector<int> node_types, top_up, nodes, active_nodes; void dfs_precalc(int u, int par) { in_time[u] = ++timer; up[u][0] = par; for (int i = 1; i < 20; i++) { if (up[u][i - 1] != -1) up[u][i] = up[up[u][i - 1]][i - 1]; } for (auto &[v, w] : adj[u]) { if (v != par) { dist[v] = dist[u] + w; dfs_precalc(v, u); } } out_time[u] = timer; } bool is_ancestor(int u, int v) { return in_time[u] <= in_time[v] && out_time[v] <= out_time[u]; } int lca(int u, int v) { if (is_ancestor(u, v)) return u; if (is_ancestor(v, u)) return v; for (int i = 19; i >= 0; i--) { if (up[u][i] != -1 && !is_ancestor(up[u][i], v)) u = up[u][i]; } return up[u][0]; } void build(const vector<int> &type_0, const vector<int> &type_1) { for (int u : active_nodes) { vt_adj[u].clear(); node_types[u] = -1; } active_nodes.clear(); top_up.clear(); nodes.clear(); auto mark = [&](int u) { if (node_types[u] == -1) { node_types[u] = -2; active_nodes.push_back(u); } }; for (int x : type_0) { nodes.push_back(x); mark(x); node_types[x] = 0; } for (int x : type_1) { nodes.push_back(x); mark(x); node_types[x] = 1; } sort(nodes.begin(), nodes.end(), [&](int u, int v) { return in_time[u] < in_time[v]; }); int sz = nodes.size(); for (int i = 0; i + 1 < sz; i++) { int l = lca(nodes[i], nodes[i + 1]); mark(l); nodes.push_back(l); } sort(nodes.begin(), nodes.end(), [&](int u, int v) { return in_time[u] < in_time[v]; }); nodes.erase(unique(nodes.begin(), nodes.end()), nodes.end()); vector<int> stk; for (int u : nodes) { while (!stk.empty() && !is_ancestor(stk.back(), u)) stk.pop_back(); if (!stk.empty()) { vt_adj[stk.back()].push_back(u); vt_adj[u].push_back(stk.back()); } else top_up.push_back(u); stk.push_back(u); } } pair<long long, long long> dfs_vt(int u, int par, long long &res) { pair<long long, long long> nearest = {inf, inf}; if (node_types[u] == 0) nearest.first = 0; if (node_types[u] == 1) nearest.second = 0; for (int v : vt_adj[u]) { if (v == par) continue; long long w = dist[v] - dist[u]; auto [z, o] = dfs_vt(v, u, res); nearest.first = min(nearest.first, z + w); nearest.second = min(nearest.second, o + w); } res = min(res, nearest.first + nearest.second); return nearest; } long long calc() { long long res = inf; for (int u : top_up) { long long cur = inf; dfs_vt(u, -1, cur); res = min(res, cur); } return res; } void Init(int N, int A[], int B[], int D[]) { n = N; timer = 0; adj.assign(n + 1, {}); up.assign(n + 1, vector<int>(20, -1)); in_time.assign(n + 1, 0); out_time.assign(n + 1, 0); dist.assign(n + 1, 0); vt_adj.assign(n + 1, {}); node_types.assign(n + 1, -1); active_nodes.clear(); for (int i = 0; i < N - 1; i++) { int u = A[i], v = B[i]; long long w = D[i]; adj[u].emplace_back(v, w); adj[v].emplace_back(u, w); } dfs_precalc(1, -1); } long long Query(int S, int X[], int T, int Y[]) { vector<int> type_0(S), type_1(T); for (int i = 0; i < S; i++) type_0[i] = X[i]; for (int i = 0; i < T; i++) type_1[i] = Y[i]; build(type_0, type_1); return calc(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...