From d0883b193fc8d098586bc6af5d6891589934e7ee Mon Sep 17 00:00:00 2001
From: Bruno Freitas Tissei <bft15@inf.ufpr.br>
Date: Sat, 4 May 2019 23:07:39 -0300
Subject: [PATCH] Add Centroid Decomposition

Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br>
---
 algorithms/graph/centroid_decomposition.cpp | 65 +++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 algorithms/graph/centroid_decomposition.cpp

diff --git a/algorithms/graph/centroid_decomposition.cpp b/algorithms/graph/centroid_decomposition.cpp
new file mode 100644
index 0000000..80a783d
--- /dev/null
+++ b/algorithms/graph/centroid_decomposition.cpp
@@ -0,0 +1,65 @@
+/// Centroid Decomposition
+///
+/// Complexity (Time): O(V log V)
+/// Complexity (Space): O(V + E)
+
+// Must be a tree
+vector<int> graph[MAX];
+
+struct CentroidDecomposition {
+  vector<int> par, size, marked;
+
+  CentroidDecomposition(int N) :
+    par(N), size(N), marked(N)
+  {
+    init();
+  }
+
+  void init() {
+    fill(all(marked), 0);
+    build(0, -1);
+  }
+
+  /// Builds the centroid decomposition of the tree recursively.
+  /// @param x initial node
+  /// @param p parent node
+  void build(int x, int p) {
+    int n = dfs(x, -1);
+    int centroid = get_centroid(x, -1, n);
+
+    marked[centroid] = 1;
+    par[centroid] = p;
+
+    for (auto i : graph[centroid])
+      if (!marked[i])
+        build(i, centroid);
+  }
+
+  /// Calculates size of every subtree (in the original tree).
+  /// @param x initial node
+  /// @param p parent node
+  int dfs(int x, int p) {
+    size[x] = 1;
+    for (auto i : graph[x])
+      if (i != p && !marked[i])
+        size[x] += dfs(i, x);
+
+    return size[x];
+  }
+
+  /// Finds centroid by recursively searching for it in the subtree 
+  /// with more than n / 2 nodes in it.
+  /// @param x initial node
+  /// @param p parent node
+  /// @param n size of initial subtree
+  int get_centroid(int x, int p, int n) {
+    for (auto i : graph[x])
+      if (i != p && size[i] > n / 2 && !marked[i])
+        return get_centroid(i, x, n);
+    return x;
+  }
+
+  int operator[](int i) {
+    return par[i];
+  }
+};
-- 
GitLab