-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcentroid_decomposition_with_lca.cpp
More file actions
75 lines (57 loc) · 1.38 KB
/
Copy pathcentroid_decomposition_with_lca.cpp
File metadata and controls
75 lines (57 loc) · 1.38 KB
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
const ll MAXN = 1e5 + 10;
const ll LG = 20;
const ll INF = 1e9;
set<ll> graph[MAXN];
ll paren[MAXN],subtree[MAXN],level[MAXN];
ll par[LG][MAXN];
ll n,m;
// FOR 0TH PARENT AND LEVEL AND PAR DP
void dfs1(ll u,ll p){
par[0][u] = p;
level[u] = level[p] + 1;
FOR(i,1,LG-1) par[i][u] = par[i-1][par[i-1][u]];
for(ll v:graph[u]){
if(v == p) continue;
dfs1(v,u);
}
}
ll lca_(ll a,ll b){
if(level[a] < level[b]) swap(a,b);
ll diff = level[a] - level[b];
FOR(i,0,LG-1) if(diff&(1<<i)) a = par[i][a];
if(a == b) return a;
RFOR(i,0,LG-1){
if(par[i][a] != par[i][b]) a = par[i][a],b = par[i][b];
}
return par[0][a];
}
ll dist(ll a,ll b){
return level[a] + level[b] - 2*level[lca_(a,b)];
}
ll nodes;
void dfs_for_subtree(ll u,ll p){
subtree[u] = 1;
nodes++;
for(ll v:graph[u]){
if(v == p) continue;
dfs_for_subtree(v,u);
subtree[u] += subtree[v];
}
}
ll dfs_for_centroid(ll u,ll p){
for(ll v:graph[u]){
if(v != p && subtree[v] > nodes/2) return dfs_for_centroid(v,u);
}
return u;
}
void decompose(ll root,ll p){
nodes = 0;
dfs_for_subtree(root,root);
ll centroid = dfs_for_centroid(root,root);
paren[centroid] = p;
for(ll v:graph[centroid]){
graph[v].erase(centroid);
decompose(v,centroid);
}
graph[centroid].clear();
}