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 <bits/stdc++.h>
#include "race.h"
using namespace std;
#define for_(i, s, e) for (int i = s; i < e; i++)
#define for__(i, s, e) for (ll i = s; i < e; i++)
#define SSTR(x) static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str()
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
//#define endl '\n'
int n, k, l, timer = 0;
vector<vector<pair<int, ll>>> adjList;
vi removed, subtreeSize, centroid, tin, tout;
vector<unordered_map<ll, vector<ii>>> paths; // {length, {child, roads}}
vector<vi> up; vector<vector<ll>> upDist;
int ans = 1e9;
int dfs(int p, int parent) {
int s = 1;
tin[p] = ++timer;
for_(i, 1, l+1) {
up[p][i] = up[up[p][i-1]][i-1];
upDist[p][i] = upDist[p][i-1] + upDist[up[p][i-1]][i-1];
}
for (auto i: adjList[p]) if (i.first != parent) {
up[i.first][0] = p;
upDist[i.first][0] = i.second;
s += dfs(i.first, p);
}
subtreeSize[p] = s;
tout[p] = ++timer;
return s;
}
bool is_ancestor(int u, int v) {
return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int lca(int u, int v) {
if (is_ancestor(u, v)) return u;
if (is_ancestor(v, u)) return v;
for (int i = l; i >= 0; --i) if (!is_ancestor(up[u][i], v)) u = up[u][i];
return up[u][0];
}
// {distance, edges}
pair<ll, int> ancDist(int u, int anc) {
if (u == anc) return {0, 0};
ll dist = 0, edges = 0;
for (int i = l; i >= 0; --i) if (!is_ancestor(up[u][i], anc)) {
dist += upDist[u][i];
edges += (1 << i);
u = up[u][i];
}
return {dist + upDist[u][0], edges+1};
}
pair<ll, int> dist(int u, int v) {
int lc = lca(u, v);
ii a = ancDist(u, lc), b = ancDist(v, lc);
//cout << u << " " << v << " -> " << a.first + b.first << ", " << a.second + b.second << endl;
return {a.first + b.first, a.second + b.second};
}
void decompose(int p, int c) {
int invalidChild = -1, sizeLimit = (subtreeSize[p] >> 1);
for (auto i: adjList[p]) if (!removed[i.first] and subtreeSize[i.first] > sizeLimit) {
invalidChild = i.first;
break;
}
if (invalidChild != -1) {
subtreeSize[p] -= subtreeSize[invalidChild];
subtreeSize[invalidChild] += subtreeSize[p];
return decompose(invalidChild, c);
}
removed[p] = true;
centroid[p] = c;
for (auto i: adjList[p]) if (!removed[i.first]) {
centroid[i.first] = p;
decompose(i.first, p);
}
}
void updateParents(int p) {
int a = p, b = centroid[p];
while (b != -1) {
ii d = dist(p, b);
paths[b][d.first].push_back({d.second, a});
a = b; b = centroid[b];
}
}
void solve(int p) {
int a = p, b = centroid[p];
while (b != -1) {
ii d = dist(p, b);
for (auto o: paths[b][k-d.first]) if (o.second != a) {
ans = min(ans, o.first + d.second);
break;
}
a = b; b = centroid[b];
}
}
int best_path(int N, int K, int H[][2], int L[]) {
n = N, k = K;
adjList.resize(n); subtreeSize.resize(n); removed.resize(n); paths.resize(n); centroid.resize(n, -1); tin.resize(n); tout.resize(n); up.resize(n);
l = ceil(log2(n));
up.assign(n, vi(l+1)); upDist.assign(n, vector<ll>(l+1));
for_(i, 0, n-1) {
int a, b; ll w; a = H[i][0], b = H[i][1]; w = L[i];
adjList[a].push_back({b, w});
adjList[b].push_back({a, w});
}
dfs(0, 0);
decompose(0, -1);
for_(i, 0, n) updateParents(i);
for_(i, 0, n) {
paths[i][0].push_back({0, -1});
for (auto o: paths[i]) {
sort(paths[i][o.first].begin(), paths[i][o.first].end());
}
}
//for_(i, 0, n) if (centroid[i] == -1) cout << i << " is the main centroid " << endl;
for_(i, 0, n) solve(i);
return (ans == 1e9 ? -1 : ans);
}
//int main() {
//#ifndef ONLINE_JUDGE
//freopen("test.in", "r", stdin);
//#endif
//ios_base::sync_with_stdio(false);
//cin.tie(0);
//int H[100000][2], L[100000];
//int N, K;
//cin >> N >> K;
//for_(i, 0, N-1) {
//int a, b; ll w; cin >> a >> b >> w;
//H[i][0] = a; H[i][1] = b;
//L[i] = w;
//}
//cout << best_path(N, K, H, L) << endl;
//return 0;
//}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |