Tree Centroid

This page introduces tree centroids and their basic properties.

Definition

If deleting a vertex TT from a tree vv leaves every connected component of T∖{v}T\setminus\{v\} with size at most half the number of vertices in the original tree, then vv 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 TT for an unrooted tree and T(v)T^{(v)} for the rooted tree with root vv. A “subtree” means a vertex together with all its descendants in a rooted tree. In T(v)T^{(v)}, the subtree corresponding to uu is Tu(v)T^{(v)}_u; 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 vv leaves the child subtrees and one “upward” subtree. If vv is the parent of uu, that upward subtree is Tu(v)T_u^{(v)}. 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 TT of a tree vv is a centroid if and only if any one of the following holds:

Unrooted-tree version

  1. After deleting vv, every component of T∖{v}T\setminus\{v\} has size at most half the original tree size.

  2. Among the largest-component sizes obtained by deleting one vertex, deleting vv gives the minimum.

  3. Among the sums of distances from all vertices to one vertex, the sum of distances to vv is minimum.

Rooted-tree version

  1. When rooted at vv, every proper subtree has size at most half the original tree size.
  2. Among the largest proper-subtree sizes over all possible roots, rooting at vv gives the minimum.
  3. Among the sums of depths from all vertices over all possible roots, rooting at vv gives the minimum.
Proof

Introduce notation. The rooted and unrooted formulations are equivalent. Let W(x)=max⁡u∼x∣Tu(x)∣W(x)=\max_{u\sim x}|T_u^{(x)}|, where u∼xu\sim x means adjacent, and let uu, where xx is the distance between S(x)=∑u∈Td(u,x)S(x)=\sum_{u\in T}d(u,x) and d(u,x)d(u,x). Definitions 1, 2, and 3 require uu, xx, and W(v)≤∣T∣/2W(v)\le |T|/2, respectively. We prove their equivalence. v∈arg⁡min⁡x∈TW(x)v\in\arg\min_{x\in T}W(x) v∈arg⁡min⁡x∈TS(x)v\in\arg\min_{x\in T}S(x)

Interpret S(x)S(x) as the sum of depths when rooted at xx. Move the root from vv to an adjacent vertex uu. Deleting (v,u)(v,u) leaves Tv(u)T_v^{(u)} and Tu(v)T_u^{(v)}; depths in the first increase by Tv(u)T_v^{(u)} and depths in the second decrease by 11, so the change in depth sum is: Tu(v)T_u^{(v)} 11

ΔSv→u=S(u)−S(v)=∣Tv(u)∣−∣Tu(v)∣=∣T∣−2∣Tu(v)∣.\Delta S_{v\to u} = S(u) - S(v) = |T_v^{(u)}| - |T_u^{(v)}| = |T| - 2|T_u^{(v)}|.

Thus Definition 1 is equivalent to requiring ΔSv→u≤0\Delta S_{v\to u}\le 0 for every neighbor vv of uu, meaning that vv is a local minimum of S(x)S(x).

Conversely, let vv be a global minimum of S(x)S(x), as in Definition 3. Consider the rooted tree vv. Let T(v)T^{(v)} be a non-root vertex; let u≠vu\neq v be the successor of vv on the path from uu to vv, and yy the predecessor of uu (possibly uu). Since xx, we obtain: vv Tu(x)⊆Ty(v)T_u^{(x)}\subseteq T_y^{(v)}

2∣Tx(u)∣=2∣T∣−2∣Tu(x)∣≥2∣T∣−2∣Ty(v)∣≥∣T∣.2|T_x^{(u)}| = 2|T| - 2|T_u^{(x)}| \ge 2|T| - 2|T_y^{(v)}| \ge |T|.

The last step uses the fact that vv is a local minimum of S(x)S(x). There are two cases:

  • Some uu satisfies 2∣Tx(u)∣=∣T∣2|T_x^{(u)}|=|T|. Then the inequality forces (x,u)=(v,y)(x,u)=(v,y) and ∣Tv(u)∣=∣Tu(v)∣=∣T∣/2|T_v^{(u)}|=|T_{u}^{(v)}| = |T|/2. Such a vertex uu is unique and adjacent to vv; every other u′≠u,vu'\neq u,v has an x′∼u′x'\sim u' with ∣Tx′(u′)∣>∣T∣/2|T_{x'}^{(u')}| > |T|/2. Thus the vertices satisfying Definition 1 are {v,u}\{v,u\}.

    Deleting any vertex leaves components whose sizes sum to ∣T∣−1|T|-1. If one component has size at least ∣T∣/2|T|/2, it is the largest. Hence W(v)=W(u)=∣T∣/2W(v)=W(u)=|T|/2 and every other u′≠u,vu'\neq u,v has W(u′)>∣T∣/2W(u') > |T|/2, so the vertices satisfying Definition 2 are arg⁡min⁡W(x)={v,u}\arg\min W(x) = \{v,u\}.

    Since ΔSv→u=0\Delta S_{v\to u} = 0, S(v)=S(u)S(v)=S(u), so vv is also a global minimum. Every other uu has an u′≠u,vu'\neq u,v with x′∼u′x'\sim u', contradicting local minimality. Thus the vertices satisfying Definition 3 are ∣Tx′(u′)∣>∣T∣/2|T_{x'}^{(u')}| > |T|/2. u′u' arg⁡min⁡S(x)={v,u}\arg\min S(x) = \{v,u\}

  • No uu satisfies 2∣Tx(u)∣=∣T∣2|T_x^{(u)}|=|T|. Then every u≠vu\neq v has x∼ux\sim u with ∣Tx(u)∣>∣T∣/2|T_x^{(u)}| > |T|/2. The preceding argument gives u≠vu\neq v and shows that W(u)>∣T∣/2W(u) > |T|/2 is not a local minimum, so only uu satisfies Definition 1 and S(x)S(x). vv arg⁡min⁡W(x)=arg⁡min⁡S(x)={v}\arg\min W(x)=\arg\min S(x) = \{v\}

In both cases the three sets coincide, proving that the definitions are equivalent.

Besides these equivalent definitions, centroids have the following standard properties:

Properties
  1. 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.
  2. Adding or deleting one leaf moves a centroid by at most one edge.
  3. When two trees are joined by an edge, a centroid of the new tree lies on the path between centroids of the original trees.
  4. 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 TT centroid vv.centroid xx centroid,centroid vv centroid T∪{x}∖{v}T\cup\{x\}\setminus\{v\} centroid,xx centroid B∪{x}B\cup\{x\}.centroid vv centroid TT centroid,centroid 2∣B∣<∣T∣2|B| < |T|,centroid 2∣B∣+1≤∣T∣2|B|+1\le |T|.centroid,centroid

    2∣B∪{x}∣=2(∣B∣+1)≤∣T∣+1=∣T∪{x}∣.2|B\cup\{x\}| = 2(|B|+1) \le |T| + 1 = |T\cup\{x\}|.

    Therefore vv remains a centroid of T∪{x}T\cup\{x\}. Even if the new tree has two centroids, the other is adjacent to vv, so the centroid moves by at most one edge.

  • Suppose TT has two centroids u,vu,v. Deleting (u,v)(u,v) gives equal components Tu(v)T_u^{(v)} and Tv(u)T_v^{(u)}, each of size ∣T∣/2|T|/2. Assume the new leaf xx is attached to vv. Tv(u)T_v^{(u)}

    ∣Tv(u)∪{x}∣=∣T∣/2+1>(∣T∣+1)/2=∣T∪{x}∣/2,|T_v^{(u)}\cup\{x\}| = |T|/2 + 1 > (|T|+1)/2 = |T\cup\{x\}|/2,

    Thus uu is no longer a centroid. Conversely, after deleting vv, the component ∣T∣/2|T|/2 still has size Tu(v)T_u^{(v)}, while the other components have total size:

    ∣T∪{x}∣−1−∣Tu(v)∣=∣T∣/2≤∣Tu(v)∣,|T\cup\{x\}| - 1 - |T_u^{(v)}| = |T|/2 \le |T_u^{(v)}|,

    Hence vv 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 TT and T′T' be (x,y)(x,y) with x∈T,y∈T′x\in T,y\in T' and TT. Assume a centroid of the new tree lies in TT. Add the vertices of T′T' one leaf at a time. Property 2 shows inductively that the centroid remains on the path from the centroid of TT to xx. vv vv TT TT vv xx vv TT xx vv xx

Property 4 follows from the heavy-light decomposition properties. Let TT be a centroid of vv. If vv is the root, this is immediate. Otherwise let vv be its parent. Since uu, the subtree containing ∣Tu(v)∣≤∣T∣/2|T_u^{(v)}| \le |T|/2 has size at least vv. Crossing a light edge on the path to the root would make it smaller than ∣T∣/2|T|/2, a contradiction; hence ∣T∣/2|T|/2 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 O(n)O(n) methods to find all centroids of a tree of size nn.

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 uu lies on a path from the centroid of a subtree rooted at one of uu's direct children to uu.

As in the DFS method above, first find the centroids of all subtrees rooted at direct children of uu (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 O(n)O(n) 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

References

This content comes from OI Wiki: Tree Centroid. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.