This page introduces tree centroids and their basic properties.
Definition
If deleting a vertex from a tree leaves every connected component of with size at most half the number of vertices in the original tree, then is the centroid of the tree. The largest component left after deleting a vertex is its weight. Thus a centroid is a vertex whose weight is at most half the tree size.
“Subtree”
This article uses unrooted trees, rooted trees, and trees rooted at a non-root vertex. We write for an unrooted tree and for the rooted tree with root . A “subtree” means a vertex together with all its descendants in a rooted tree. In , the subtree corresponding to is ; this includes the whole tree. A subtree excluding the whole tree is called a proper subtree.
In an unrooted tree, “subtree” often means a connected subgraph. When discussing centroids, some authors instead mean a maximal connected subgraph excluding a specified vertex, or one of the two components obtained by deleting an edge. These definitions give the same collection and never include the whole tree. Because it differs from the rooted-tree usage, this article avoids “subtree” for unrooted trees.
In applications there is often an implicit root. Deleting a non-root vertex leaves the child subtrees and one “upward” subtree. If is the parent of , that upward subtree is . We explicitly call such a component an upward subtree; unless stated otherwise, “subtree” excludes it.
These components are themselves unrooted trees. Deleting a centroid splits a tree into trees of size at most half the original size, enabling divide-and-conquer on trees. This is centroid decomposition.
Properties
This section discusses centroid properties. First, there are equivalent definitions.
Equivalent Definitions
A vertex of a tree is a centroid if and only if any one of the following holds:
Unrooted-tree version
-
After deleting , every component of has size at most half the original tree size.
-
Among the largest-component sizes obtained by deleting one vertex, deleting gives the minimum.
-
Among the sums of distances from all vertices to one vertex, the sum of distances to is minimum.
Rooted-tree version
- When rooted at , every proper subtree has size at most half the original tree size.
- Among the largest proper-subtree sizes over all possible roots, rooting at gives the minimum.
- Among the sums of depths from all vertices over all possible roots, rooting at gives the minimum.
Proof
Introduce notation. The rooted and unrooted formulations are equivalent. Let , where means adjacent, and let , where is the distance between and . Definitions 1, 2, and 3 require , , and , respectively. We prove their equivalence.
Interpret as the sum of depths when rooted at . Move the root from to an adjacent vertex . Deleting leaves and ; depths in the first increase by and depths in the second decrease by , so the change in depth sum is:
Thus Definition 1 is equivalent to requiring for every neighbor of , meaning that is a local minimum of .
Conversely, let be a global minimum of , as in Definition 3. Consider the rooted tree . Let be a non-root vertex; let be the successor of on the path from to , and the predecessor of (possibly ). Since , we obtain:
The last step uses the fact that is a local minimum of . There are two cases:
-
Some satisfies . Then the inequality forces and . Such a vertex is unique and adjacent to ; every other has an with . Thus the vertices satisfying Definition 1 are .
Deleting any vertex leaves components whose sizes sum to . If one component has size at least , it is the largest. Hence and every other has , so the vertices satisfying Definition 2 are .
Since , , so is also a global minimum. Every other has an with , contradicting local minimality. Thus the vertices satisfying Definition 3 are .
-
No satisfies . Then every has with . The preceding argument gives and shows that is not a local minimum, so only satisfies Definition 1 and .
In both cases the three sets coincide, proving that the definitions are equivalent.
Besides these equivalent definitions, centroids have the following standard properties:
Properties
- If a tree has more than one centroid, it has exactly two. They are adjacent, and deleting their connecting edge leaves two components of equal size.
- Adding or deleting one leaf moves a centroid by at most one edge.
- When two trees are joined by an edge, a centroid of the new tree lies on the path between centroids of the original trees.
- A rooted tree's centroid lies on the heavy chain containing the root. The centroid of a tree is an ancestor of the centroid of the subtree rooted at the root's heavy child.
Proof
Property 1 follows from the proof of the equivalent definitions.
For Property 2, consider adding a leaf. There are two cases:
-
centroid centroid .centroid centroid,centroid centroid centroid, centroid .centroid centroid centroid,centroid ,centroid .centroid,centroid
Therefore remains a centroid of . Even if the new tree has two centroids, the other is adjacent to , so the centroid moves by at most one edge.
-
Suppose has two centroids . Deleting gives equal components and , each of size . Assume the new leaf is attached to .
Thus is no longer a centroid. Conversely, after deleting , the component still has size , while the other components have total size:
Hence remains a centroid. The new tree has an odd number of vertices, so its centroid is unique and moves by at most one edge.
In both cases, the new centroid lies on the path from an old centroid to the newly added leaf.
Property 3 follows by induction. Let the new edge joining and be with and . Assume a centroid of the new tree lies in . Add the vertices of one leaf at a time. Property 2 shows inductively that the centroid remains on the path from the centroid of to .
Property 4 follows from the heavy-light decomposition properties. Let be a centroid of . If is the root, this is immediate. Otherwise let be its parent. Since , the subtree containing has size at least . Crossing a light edge on the path to the root would make it smaller than , a contradiction; hence lies on the root's heavy chain. The heavy-child construction and Property 3 then show that the new centroid is an ancestor of the old one.
Methods
The equivalent definitions give two methods to find all centroids of a tree of size .
DFS Subtree-Size Method
Use DFS to compute every subtree size. For each vertex, record the sizes of child subtrees and obtain the upward-subtree size by subtracting the current subtree size from the total; the definition then identifies the centroids.
Reference implementation
const int MAXN = 50005;
int n;
// This code assumes vertices are numbered from 1, so i\in[1,n]
int siz[MAXN], // size of this vertex (all subtree vertices plus the vertex itself)
weight[MAXN]; // weight of this vertex, the maximum child-subtree size
vector<int> centroids; // store centroid vertex numbers
vector<int> g[MAXN];
void dfs(int cur, int fa) { // cur is the current vertex
siz[cur] = 1;
weight[cur] = 0;
for (int v : g[cur]) {
if (v != fa) { // v is the vertex reached by this directed edge
dfs(v, cur);
siz[cur] += siz[v];
weight[cur] = max(weight[cur], siz[v]);
}
}
weight[cur] = max(weight[cur], n - siz[cur]);
if (weight[cur] <= n / 2) { // apply the centroid definition
centroids.push_back(cur);
}
}
void get_centroids() { dfs(1, 0); }
Rerooting DP for Depth Sums
Rerooting DP can compute the sum of depths (distances to the root) for every possible root. By the definition, choose the vertex minimizing this sum.
Reference implementation
const int N = 50005;
int n, siz[N];
long long dp[N], ans[N];
vector<int> g[N], centroids;
// sum of distances from vertex 1 to all other vertices
void dfs1(int u, int fa) {
siz[u] = 1;
dp[u] = 0;
for (int v : g[u]) {
if (v == fa) continue;
dfs1(v, u);
siz[u] += siz[v];
dp[u] += dp[v] + siz[v]; // sum of distances from subtree vertices to u
}
}
// compute the distance sum for every possible root by rerooting DP
void dfs2(int u, int fa) {
for (int v : g[u]) {
if (v == fa) continue;
ans[v] = ans[u] - siz[v] + (n - siz[v]);
dfs2(v, u);
}
}
// find the centroid of the tree
void get_centroids() {
dfs1(1, 0);
ans[1] = dp[1];
dfs2(1, 0);
long long mini = std::numeric_limits<long long>::max();
for (int i = 1; i <= n; i++) {
if (ans[i] < mini) {
mini = ans[i];
centroids = {i};
} else if (ans[i] == mini)
centroids.push_back(i);
}
}
Example
Codeforces Round 359 (Div. 1) B. Kay and Snowflake
Given a rooted tree, find the centroid of every subtree.
Solution Idea
By Property 3, the centroid of a subtree rooted at lies on a path from the centroid of a subtree rooted at one of 's direct children to .
As in the DFS method above, first find the centroids of all subtrees rooted at direct children of (a leaf's centroid is itself), then move upward along the path and test which vertices are centroids.
All subtree centroids can be found in time.
Reference code
#include <iostream>
#include <vector>
using namespace std;
constexpr int N = 3e5 + 5;
int n, q; // number of vertices and queries
int fa[N];
vector<int> son[N];
int siz[N], // subtree sizes
ans[N], // centroid of the subtree rooted at u is ans[u]
weight[N]; // vertex weight, excluding the upward subtree
void dfs(int u) {
siz[u] = 1, ans[u] = u;
for (int v : son[u]) {
dfs(v);
siz[u] += siz[v];
weight[u] = max(weight[u], siz[v]);
}
for (int v : son[u]) {
int p = ans[v];
while (p != u) {
if (max(weight[p], siz[u] - siz[p]) <= siz[u] / 2) {
ans[u] = p;
break;
} else
p = fa[p];
}
}
}
int main() {
ios::sync_with_stdio(false);
cin >> n >> q;
for (int v = 2; v <= n; v++) cin >> fa[v], son[fa[v]].push_back(v);
dfs(1);
while (q--) {
int u;
cin >> u;
cout << ans[u] << '\n';
}
return 0;
}
Exercises
- Gym 101649G Godfather
- POJ 1655 Balancing Art
- Luogu P1364 Hospital Setup
- Codeforces 1406C Link Cut Centroids
- Codeforces 708C Centroids
References
- Some Centroid Properties and Dynamic Maintenance - fanhq666 (reposted on cnblogs)
- Tree Diameter, Tree Centroid, and Centroid Decomposition - cyendra
- Properties and Proofs of Tree Centroids - suxxsfe
- Information Olympiad Dictionary, Chapter 2.4.7.11, section 1: Tree Centroids