This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "factories.h"
#include <bits/stdc++.h>
using namespace std;
#define dbg(x) cerr << #x << ": " << x << endl;
const int MAX_N = 500'000;
const int MAX_LOG = 20;
const long long INF = 1e16;
vector<pair<int, int>> g[MAX_N];
int sz[MAX_N];
int level[MAX_N];
bool used[MAX_N];
long long dist[MAX_LOG][MAX_N];
vector<int> centroids[MAX_N];
long long distances[MAX_N];
inline void dfs_calc(int v, int p, int curr_weight, int c) {
sz[v] = 1;
if (c != -1) {
dist[level[c]][v] = dist[level[c]][p] + curr_weight;
centroids[v].push_back(c);
}
for (const auto& [u, weight] : g[v]) {
if (used[u] || u == p) continue;
dfs_calc(u, v, weight, c);
sz[v] += sz[u];
}
}
inline int find_centroid(int v, int p, int n) {
for (const auto& [u, w] : g[v]) {
if (used[u] || u == p) continue;
if (2 * sz[u] > n) {
return find_centroid(u, v, n);
}
}
return v;
}
inline void dfs_build(int v = 0, int p = -1, int curr_weight = -1) {
dfs_calc(v, p, curr_weight, p);
int c = find_centroid(v, -1, sz[v]);
if (p != -1) level[c] = level[p] + 1;
centroids[c].push_back(c);
used[c] = true;
for (const auto& [u, weight] : g[c]) {
if (!used[u]) {
dfs_build(u, c, weight);
}
}
}
inline void add_vertex(int v) {
for (int c : centroids[v]) {
distances[c] = min(distances[c], dist[level[c]][v]);
}
}
inline void remove_vertex(int v) {
for (int c : centroids[v]) {
distances[c] = INF;
}
}
inline long long get_closest(int v) {
long long res = INF;
for (int c : centroids[v]) {
if (distances[c] != INF) {
res = min(res, dist[level[c]][v] + distances[c]);
}
}
return res;
}
void Init(int n, int a[], int b[], int d[]) {
for (int i = 0; i < n - 1; ++i) {
int u = a[i];
int v = b[i];
g[u].emplace_back(v, d[i]);
g[v].emplace_back(u, d[i]);
}
fill_n(distances, MAX_N, INF);
dfs_build();
}
long long Query(int n, int x[], int m, int y[]) {
for (int i = 0; i < n; ++i) {
add_vertex(x[i]);
}
long long res = INF;
for (int i = 0; i < m; ++i) {
res = min(res, get_closest(y[i]));
}
for (int i = 0; i < n; ++i) {
remove_vertex(x[i]);
}
return res;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |