-
Notifications
You must be signed in to change notification settings - Fork 0
/
Centroid Decomposition.cpp
89 lines (88 loc) · 2.17 KB
/
Centroid Decomposition.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*---------Preprocessing----------*/
vector<int>adj[N];
int del[N];
/*------LCA Code will be here----*/
int parent[N],sparse[N][22],level[N];
void dfs(int u,int from, int d){
level[u]=d;
for(int v : adj[u]){
if(from==v)continue;
parent[v]=u;
dfs(v,u,d+1);
}
}
void lca(int n){
SET(sparse);
for(int i=0;i<n;i++)sparse[i][0]=parent[i];
for(int j=1;(1<<j)<n;j++){
for(int i=0;i<n;i++){
if(sparse[i][j-1]!=-1)
sparse[i][j]=sparse[sparse[i][j-1]][j-1];
}
}
}
int LCA(int p,int q){
if(level[p]<level[q])swap(p,q);
int log;
for(log=1;1<<log<=level[p];log++);
log--;
for(int i=log;i>=0;i--)
if(level[p]-(1<<i)>=level[q]) p=sparse[p][i];
if(p==q)return p;
for(int i=log;i>=0;i--){
if(sparse[p][i]!=-1 && sparse[p][i]!=sparse[q][i]){
p=sparse[p][i];
q=sparse[q][i];
}
}
return parent[p];
}
int dist(int p, int q){
int res = level[p]+level[q]-(2*level[LCA(p,q)]);
return res;
}
/*-------Decomposition Part--------*/
int sub[N], par[N];
void dfs(int u, int from){
sub[u] = 1;
for(int v : adj[u]){
if(v == from || del[v])continue;
dfs(v, u);
sub[u] += sub[v];
}
}
int find_centroid(int u, int from, int range){
for(int v : adj[u]){
if(v == from || del[v])continue;
if(sub[v] > range) return find_centroid(v, u, range);
}
return u;
}
void build_tree(int u, int from){
dfs(u, -1);
int c = find_centroid(u, -1, sub[u]/2);
//Delete all the edges that are linked with current centroid
del[c] = 1;
par[c] = from;
for(int v : adj[c]){
if(v == from || del[v])continue;
build_tree(v, c);
}
}
/*------Handle Queries------*/
int ans[N];
void update(int node){
int src = node;
while(node != -1){
ans[node] = min(ans[node], dist(node,src));
node = par[node];
}
}
int query(int node){
int res = inf, src = node;
while(node != -1){
res = min(res, ans[node]+dist(node,src));
node = par[node];
}
return res;
}