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