forked from bicsi/code_snippets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
centroid.cpp
65 lines (54 loc) · 1.3 KB
/
centroid.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
struct CentroidDecomposer {
int n;
vector<set<int>> G;
vector<int> Size;
// Depth and parent in the centroid tree
vector<int> CD, CP;
CentroidDecomposer(int n) :
n(n), G(n), Size(n), CD(n), CP(n) {}
void AddEdge(int a, int b) {
G[a].insert(b);
G[b].insert(a);
}
int rec_size, rec_centr;
void ComputeSizeAndCentroid(int node, int par) {
Size[node] = 1;
int max_size = 0;
for(auto vec : G[node])
if(vec != par) {
ComputeSizeAndCentroid(vec, node);
Size[node] += Size[vec];
max_size = max(max_size, Size[vec]);
}
max_size = max(max_size, rec_size - Size[node]);
if(2 * max_size <= rec_size)
rec_centr = node;
}
void DoUsefulDFS(int node, int par, int cd) {
Size[node] = 1;
for(auto vec : G[node])
if(vec != par) {
DoUsefulDFS(vec, node, cd);
Size[node] += Size[vec];
}
}
void RecDecomp(int node, int size, int cp, int cd) {
// node -> centroid(node)
rec_size = size;
ComputeSizeAndCentroid(node, -1);
node = rec_centr;
CP[node] = cp;
CD[node] = cd;
// You can do whichever DFS you want here
DoUsefulDFS(node, -1, cd);
for(auto vec : G[node]) {
G[vec].erase(node);
RecDecomp(vec, Size[vec], node, cd + 1);
}
}
void Decompose(int root = 0) {
RecDecomp(root, n, -1, 0);
for(auto x : CD)
assert(x <= __lg(n) + 1);
}
};