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>
typedef long long ll;
using namespace std;
/*************** LCA ******************/
const int N = 5 * 1e5 + 1 ;
const int Log = 20;
const ll inf = 1e18 ;
int n ;
int P[Log][N], L[N] ;
ll cost[N];
vector < pair < int, int > > G[N];
void dfs(int u, int p, int d, ll w) {
P[0][u] = p ;
L[u] = d ;
cost[u] = w;
for(auto e : G[u]) {
int v = e.first, c = e.second ;
if(v == p)
continue ;
dfs(v, u, d + 1, w + c);
}
}
void dp() {
for(int j = 1 ; (1 << j) < n ; j++)
for(int i = 0 ; i < n ; i++)
if(P[j - 1][i] != -1)
P[j][i] = P[j - 1][P[j - 1][i]] ;
}
int lca(int u, int v) {
if(L[u] < L[v])
swap(u, v);
int i, log ;
for(log = 1 ; (1 << log) <= L[u] ; log++);
log -- ;
for(i = log ; i >= 0 ; i--) {
if(L[u] - (1 << i) >= L[v])
u = P[i][u] ;
}
if(u == v)
return u ;
for(i = log ; i >= 0 ; i--) {
if(P[i][u] != -1 && P[i][u] != P[i][v])
u = P[i][u], v = P[i][v] ;
}
return P[0][u];
}
inline ll dist(int &u, int &v) {
return cost[u] + cost[v] - 2 * cost[lca(u, v)];
}
/*************** Centroid ******************/
int sub[N], p[N] , par[N];
bool blocked[N];
void get_size(int u, int pa) {
p[u] = pa ;
sub[u] = 1 ;
for(auto e : G[u]) {
int v = e.first ;
if(v == pa || blocked[v])
continue ;
get_size(v, u);
sub[u] += sub[v];
}
}
int get_centroid(int src) {
get_size(src, src);
int centroid = src, best = sub[src] ;
queue < int > Q ;
Q.emplace(src);
while(!Q.empty()) {
int u = Q.front();
Q.pop();
int size = sub[src] - sub[u];
for(auto e : G[u]) {
int v = e.first;
if(v == p[u] || blocked[v])
continue ;
Q.emplace(v);
size = max(size, sub[v]);
}
if(best > size) {
best = size;
centroid = u ;
}
}
blocked[centroid] = true;
for(auto e : G[centroid]) {
int v = e.first ;
if(blocked[v]) continue ;
int child = get_centroid(v);
par[child] = centroid ;
}
return centroid ;
}
ll ans[N];
int vis[N];
int t = 1 ;
vector < ll > dis[N];
inline void update(int &u) {
int v = u ;
int i = 0 ;
while(true) {
if(vis[v] != t)
vis[v] = t , ans[v] = inf ;
ans[v] = min(ans[v], dis[u][i]);
if(v == par[v]) break ;
v = par[v];
i++ ;
}
}
inline ll query(int &u) {
int v = u ;
ll ret = inf ;
int i = 0 ;
while(true) {
if(vis[v] != t)
vis[v] = t , ans[v] = inf ;
ret = min(ret, ans[v] + dis[u][i]);
if(v == par[v]) break ;
v = par[v];
i++ ;
}
return ret;
}
ll Query(int S, int X[], int T, int Y[]) {
t++ ;
for(int i = 0 ; i < T ; i++) {
update(Y[i]);
}
ll ret = inf ;
for(int i = 0 ; i < S ; i++) {
ret = min(ret, query(X[i]));
}
return ret;
}
void Init(int N, int A[], int B[], int D[]) {
n = N ;
for(int i = 0 ; i < n - 1 ; i++) {
int u = A[i], v = B[i], w = D[i];
G[u].push_back({v, w});
G[v].push_back({u, w});
}
memset(P , -1 , sizeof P);
dfs(0, -1, 0, 0);
dp();
int root = get_centroid(0);
par[root] = root;
for(int i = 0 ; i < n ; i++) {
int v = i ;
while(true) {
dis[i].push_back(dist(v, i));
if(v == par[v]) break ;
v = par[v];
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |