Open in App
Not now

# Number of K-length paths in a Tree

• Difficulty Level : Hard
• Last Updated : 21 Mar, 2023

Given a tree of N nodes and an integer K, the task is to find the total number of paths having length K.

Examples:

Input: N = 5, K = 2
tree =           1
/  \
2    5
/  \
3    4
Output: 4
Explanation: The paths having length 2 are
1 – 2 – 3, 1 – 2 – 4, 2 – 1 – 5, 3 – 2 – 4

Input: N = 2, K = 2
tree =       1
/
2
Output: 0
Explanation: There is no path in the tree having length 2.

Intuition: The main idea is to find the K-length paths from each node and add them.

1. Find the number of K-length paths ‘originating’ from a given node ‘node’. ‘Originating’ here means, ‘node’ will have the smallest depth among all the nodes in the path. For example, 2-length paths originating from 1 are shown in the below diagram.
2. Sum above value for all the nodes and it will be the required answer.

Naive Approach: To compute the K-length paths originating from ‘node’ two DFS are used. Say this entire process is: paths_originating_from(node)

1. Suppose ‘node’ has multiple children and currently child ‘u’ is being processed.
2. For all the previous children, the frequency of nodes at a particular depth has been calculated. More formally, freq[d] gives the number of nodes at depth ‘d’ when only children of ‘node’ before ‘u’ have been processed.
3. If there is a node ‘x’ at depth ‘d’, number of K length paths originating from ‘node’ and passing through ‘x’ will be freq[K – d].
4. The first DFSF would contribute to the final answer, and the second DFS would update the freq[] array for future use.
5. Sum-up ‘paths_originating_from(node)’ for all nodes of the tree, this will be the required answer.

See the image below to understand the 2nd point better.

Below is the implementation of the above approach.

## C++

 `// C++ code to implement above approach` `#include ` `using` `namespace` `std;`   `int` `mx_depth = 0, ans = 0;` `int` `N, K;` `vector<``int``> freq;` `vector > g;`   `// This dfs is responsible for calculating ans ` `// and updating freq vector` `void` `dfs(``int` `node, ``int` `par, ``int` `depth, ` `         ``bool` `contri)` `{` `    ``if` `(depth > K)` `        ``return``;` `    ``mx_depth = max(mx_depth, depth);`   `    ``if` `(contri) {` `        ``ans += freq[K - depth];` `    ``}` `    ``else` `{` `        ``freq[depth]++;` `    ``}`   `    ``for` `(``auto` `nebr : g[node]) {` `        ``if` `(nebr != par) {` `            ``dfs(nebr, node, depth + 1, ` `                ``contri);` `        ``}` `    ``}` `}`   `// Function to calculate K length paths ` `// originating from node` `void` `paths_originating_from(``int` `node, ` `                            ``int` `par)` `{` `    ``mx_depth = 0;` `    ``freq[0] = 1;`   `    ``// For every not-removed nebr, ` `    ``// calculate its contribution, ` `    ``// then update freq vector for it` `    ``for` `(``auto` `nebr : g[node]) {` `        ``if` `(nebr != par) {` `            ``dfs(nebr, node, 1, ``true``);` `            ``dfs(nebr, node, 1, ``false``);` `        ``}` `    ``}`   `    ``// Re-initialize freq vector` `    ``for` `(``int` `i = 0; i <= mx_depth; ++i) {` `        ``freq[i] = 0;` `    ``}`   `    ``// Repeat the same for children` `    ``for` `(``auto` `nebr : g[node]) {` `        ``if` `(nebr != par) {` `            ``paths_originating_from(nebr, ` `                                   ``node);` `        ``}` `    ``}` `}`   `// Utility method to add edges to tree` `void` `edge(``int` `a, ``int` `b)` `{` `    ``a--;` `    ``b--;` `    ``g[a].push_back(b);` `    ``g[b].push_back(a);` `}`   `// Driver code` `int` `main()` `{` `    ``N = 5, K = 2;` `    ``freq = vector<``int``>(N);` `    ``g = vector >(N);`   `    ``edge(1, 2);` `    ``edge(1, 5);` `    ``edge(2, 3);` `    ``edge(2, 4);` `  `  `    ``paths_originating_from(0, -1);` `    ``cout << ans << endl;` `}`

## Java

 `import` `java.io.*;` `import` `java.util.*;`   `public` `class` `Main {` `  ``static` `int` `N, K, mx_depth = ``0``, ans = ``0``;` `  ``;` `  ``static` `void` `edge(``int` `a, ``int` `b,` `                   ``ArrayList > g)` `  ``{` `    ``a--;` `    ``b--;` `    ``g.get(a).add(b);` `    ``g.get(b).add(a);` `  ``}` `  ``// This dfs is responsible for calculating ans` `  ``// and updating freq vector` `  ``static` `void` `dfs(``int` `node, ``int` `par, ``int` `depth,` `                  ``boolean` `contri, ArrayList freq,` `                  ``ArrayList > g)` `  ``{` `    ``if` `(depth > K)` `      ``return``;` `    ``mx_depth = Math.max(mx_depth, depth);`   `    ``if` `(contri) {` `      ``ans += freq.get(K - depth);` `    ``}` `    ``else` `{` `      ``freq.set(depth, freq.get(depth) + ``1``);` `    ``}`   `    ``for` `(``int` `i = ``0``; i < g.get(node).size(); i++) {` `      ``int` `nebr = g.get(node).get(i);` `      ``if` `(nebr != par) {` `        ``dfs(nebr, node, depth + ``1``, contri, freq, g);` `      ``}` `    ``}` `  ``}`   `  ``// Function to calculate K length paths` `  ``// originating from node` `  ``static` `void` `    ``paths_originating_from(``int` `node, ``int` `par,` `                           ``ArrayList freq,` `                           ``ArrayList > g)` `  ``{` `    ``mx_depth = ``0``;` `    ``freq.set(``0``, ``1``);`   `    ``// For every not-removed nebr,` `    ``// calculate its contribution,` `    ``// then update freq vector for it`   `    ``for` `(``int` `i = ``0``; i < g.get(node).size(); i++) {` `      ``int` `nebr = g.get(node).get(i);` `      ``if` `(nebr != par) {` `        ``dfs(nebr, node, ``1``, ``true``, freq, g);` `        ``dfs(nebr, node, ``1``, ``false``, freq, g);` `      ``}` `    ``}`   `    ``// Re-initialize freq vector` `    ``for` `(``int` `i = ``0``; i <= mx_depth; ++i) {` `      ``freq.set(i, ``0``);` `    ``}`   `    ``// Repeat the same for children` `    ``for` `(``int` `i = ``0``; i < g.get(node).size(); i++) {` `      ``int` `nebr = g.get(node).get(i);` `      ``if` `(nebr != par) {` `        ``paths_originating_from(nebr, node, freq, g);` `      ``}` `    ``}` `  ``}` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``N = ``5``;` `    ``K = ``2``;` `    ``ArrayList freq = ``new` `ArrayList();` `    ``for` `(``int` `i = ``0``; i < N; i++)` `      ``freq.add(``0``);` `    ``ArrayList > g` `      ``= ``new` `ArrayList >();` `    ``for` `(``int` `i = ``0``; i < N; i++)` `      ``g.add(``new` `ArrayList());`   `    ``edge(``1``, ``2``, g);` `    ``edge(``1``, ``5``, g);` `    ``edge(``2``, ``3``, g);` `    ``edge(``2``, ``4``, g);` `    ``paths_originating_from(``0``, -``1``, freq, g);` `    ``System.out.println(ans);` `  ``}` `}`   `// This code is contributed by garg28harsh.`

## Python3

 `# Python code to implement above approach` `mx_depth ``=` `0` `ans ``=` `0` `N ``=` `5` `K ``=` `2` `freq ``=` `[``0``] ``*` `N` `g ``=` `[[] ``for` `_ ``in` `range``(N)]`   `# This dfs is responsible for calculating ans` `# and updating freq vector`     `def` `dfs(node, par, depth, contri):` `    ``global` `mx_depth, ans, freq` `    ``if` `depth > K:` `        ``return` `    ``mx_depth ``=` `max``(mx_depth, depth)`   `    ``if` `contri:` `        ``ans ``+``=` `freq[K ``-` `depth]` `    ``else``:` `        ``freq[depth] ``+``=` `1`   `    ``for` `nebr ``in` `g[node]:` `        ``if` `nebr !``=` `par:` `            ``dfs(nebr, node, depth ``+` `1``, contri)`   `# Function to calculate K length paths` `# originating from node`     `def` `paths_originating_from(node, par):` `    ``global` `mx_depth, freq` `    ``mx_depth ``=` `0` `    ``freq[``0``] ``=` `1`   `    ``# For every not-removed nebr,` `    ``# calculate its contribution,` `    ``# then update freq vector for it` `    ``for` `nebr ``in` `g[node]:` `        ``if` `nebr !``=` `par:` `            ``dfs(nebr, node, ``1``, ``True``)` `            ``dfs(nebr, node, ``1``, ``False``)`   `    ``# Re-initialize freq vector` `    ``freq ``=` `[``0``] ``*` `(mx_depth ``+` `1``)`   `    ``# Repeat the same for children` `    ``for` `nebr ``in` `g[node]:` `        ``if` `nebr !``=` `par:` `            ``paths_originating_from(nebr, node)`   `# Utility method to add edges to tree`     `def` `edge(a, b):` `    ``a ``-``=` `1` `    ``b ``-``=` `1` `    ``g[a].append(b)` `    ``g[b].append(a)`     `# Driver code` `edge(``1``, ``2``)` `edge(``1``, ``5``)` `edge(``2``, ``3``)` `edge(``2``, ``4``)`   `paths_originating_from(``0``, ``-``1``)` `print``(ans)`

## C#

 `// C# code to implement above approach` `using` `System;` `using` `System.Collections.Generic;`   `class` `Program {` `    ``static` `int` `mx_depth = 0, ans = 0;` `    ``static` `int` `N, K;` `    ``static` `List<``int``> freq;` `    ``static` `List > g;`   `    ``// This dfs is responsible for calculating ans` `    ``// and updating freq vector` `    ``static` `void` `dfs(``int` `node, ``int` `par, ``int` `depth,` `                    ``bool` `contri)` `    ``{` `        ``if` `(depth > K)` `            ``return``;` `        ``mx_depth = Math.Max(mx_depth, depth);`   `        ``if` `(contri) {` `            ``ans += freq[K - depth];` `        ``}` `        ``else` `{` `            ``freq[depth]++;` `        ``}`   `        ``foreach``(``int` `nebr ``in` `g[node])` `        ``{` `            ``if` `(nebr != par) {` `                ``dfs(nebr, node, depth + 1, contri);` `            ``}` `        ``}` `    ``}`   `    ``// Function to calculate K length paths` `    ``// originating from node` `    ``static` `void` `paths_originating_from(``int` `node, ``int` `par)` `    ``{` `        ``mx_depth = 0;` `        ``freq[0] = 1;`   `        ``// For every not-removed nebr,` `        ``// calculate its contribution,` `        ``// then update freq vector for it` `        ``foreach``(``int` `nebr ``in` `g[node])` `        ``{` `            ``if` `(nebr != par) {` `                ``dfs(nebr, node, 1, ``true``);` `                ``dfs(nebr, node, 1, ``false``);` `            ``}` `        ``}`   `        ``// Re-initialize freq vector` `        ``for` `(``int` `i = 0; i <= mx_depth; ++i) {` `            ``freq[i] = 0;` `        ``}`   `        ``// Repeat the same for children` `        ``foreach``(``int` `nebr ``in` `g[node])` `        ``{` `            ``if` `(nebr != par) {` `                ``paths_originating_from(nebr, node);` `            ``}` `        ``}` `    ``}`   `    ``// Utility method to add edges to tree` `    ``static` `void` `edge(``int` `a, ``int` `b)` `    ``{` `        ``a--;` `        ``b--;` `        ``g[a].Add(b);` `        ``g[b].Add(a);` `    ``}`   `    ``// Driver code` `    ``static` `void` `Main()` `    ``{` `        ``N = 5;` `        ``K = 2;` `        ``freq = ``new` `List<``int``>(N);` `        ``g = ``new` `List >(N);`   `        ``for` `(``int` `i = 0; i < N; i++) {` `            ``freq.Add(0);` `            ``g.Add(``new` `List<``int``>());` `        ``}`   `        ``edge(1, 2);` `        ``edge(1, 5);` `        ``edge(2, 3);` `        ``edge(2, 4);`   `        ``paths_originating_from(0, -1);` `        ``Console.WriteLine(ans);` `    ``}` `}`   `// This code is contributed by rutikbhosale.`

## Javascript

 `// Javascript code to implement above approach`   `let max_Depth = 0, ans = 0, N, K, freq = [];` `let g = ``new` `Array(1000).fill(0).map(() => ``new` `Array(0))`   `// This dfs is responsible for calculating ans ` `// and updating freq vector` `function` `dfs(node, par, depth, contri) {` `    ``if` `(depth > K)` `        ``return``;` `    ``mx_depth = Math.max(mx_depth, depth);`   `    ``if` `(contri) {` `        ``ans += freq[K - depth];` `    ``}` `    ``else` `{` `        ``freq[depth]++;` `    ``}`   `    ``for` `(let nebr of g[node]) {` `        ``if` `(nebr != par) {` `            ``dfs(nebr, node, depth + 1,` `                ``contri);` `        ``}` `    ``}` `}`   `// Function to calculate K length paths ` `// originating from node` `function` `paths_originating_from(node, par) {` `    ``mx_depth = 0;` `    ``freq[0] = 1;`   `    ``// For every not-removed nebr, ` `    ``// calculate its contribution, ` `    ``// then update freq vector for it` `    ``for` `(let nebr of g[node]) {` `        ``if` `(nebr != par) {` `            ``dfs(nebr, node, 1, ``true``);` `            ``dfs(nebr, node, 1, ``false``);` `        ``}` `    ``}`   `    ``// Re-initialize freq vector` `    ``for` `(let i = 0; i <= mx_depth; ++i) {` `        ``freq[i] = 0;` `    ``}`   `    ``// Repeat the same for children` `    ``for` `(let nebr of g[node]) {` `        ``if` `(nebr != par) {` `            ``paths_originating_from(nebr,` `                ``node);` `        ``}` `    ``}` `}`   `// Utility method to add edges to tree` `function` `edge(a, b) {` `    ``a--;` `    ``b--;` `    ``g[a].push(b);` `    ``g[b].push(a);` `}`   `// Driver code`   `N = 5;` `K = 2;` `freq = ``new` `Array(N).fill(0);` `g = ``new` `Array(1000).fill(0).map(() => ``new` `Array());`   `edge(1, 2);` `edge(1, 5);` `edge(2, 3);` `edge(2, 4);`   `paths_originating_from(0, -1);` `console.log(ans)`

Output

`4`

Time Complexity: O(N * H) where H is the height of the tree which can be N at max
Auxiliary Space: O(N)

Efficient Approach: This approach is based on the concept of Centroid Decomposition. The steps are as follows:

1. Find the centroid of current tree T.
2. All ‘not-removed’ nodes reachable from T belong to its sub-tree. Call paths_originating_from(T), then mark T as ‘removed’.
3. Repeat the above process for all ‘not-removed’ neighbors of T.

The following figure shows a tree with current centroid and its sub-tree. Note that nodes with thick borders have already been selected as centroids previously and do not belong to the sub-tree of the current centroid.

Below is the implementation of the above approach.

## C++

 `// C++ code to implement above approach` `#include ` `using` `namespace` `std;`   `// Struct for centroid decomposition` `struct` `CD {` `    ``// 1. mx_depth will be used to store ` `    ``// the height of a node` `    ``// 2. g[] is adjacency list for tree` `    ``// 3. freq[] stores frequency of nodes ` `    ``// at particular height, it is maintained ` `    ``// for children of a node` `    ``int` `n, k, mx_depth, ans;` `    ``vector<``bool``> removed;` `    ``vector<``int``> size, freq;` `    ``vector > g;`   `    ``// Constructor for struct` `    ``CD(``int` `n1, ``int` `k1)` `    ``{` `        ``n = n1;` `        ``k = k1;` `        ``ans = mx_depth = 0;`   `        ``g.resize(n);` `        ``size.resize(n);` `        ``freq.resize(n);` `        ``removed.assign(n, ``false``);` `    ``}`   `    ``// Utility method to add edges to tree` `    ``void` `edge(``int` `u, ``int` `v)` `    ``{` `        ``u--;` `        ``v--;` `        ``g[u].push_back(v);` `        ``g[v].push_back(u);` `    ``}`   `    ``// Finds size of a subtree, ` `    ``// ignoring removed nodes in the way` `    ``int` `get_size(``int` `node, ``int` `par)` `    ``{` `        ``if` `(removed[node])` `            ``return` `0;` `        ``size[node] = 1;`   `        ``for` `(``auto` `nebr : g[node]) {` `            ``if` `(nebr != par) {` `                ``size[node] += get_size(nebr, ` `                                       ``node);` `            ``}` `        ``}`   `        ``return` `size[node];` `    ``}`   `    ``// Calculates centroid of a subtree ` `    ``// of 'node' of size 'sz'` `    ``int` `get_centroid(``int` `node, ``int` `par, ` `                     ``int` `sz)` `    ``{` `        ``for` `(``auto` `nebr : g[node]) {` `            ``if` `(nebr != par && !removed[nebr]` `                ``&& size[nebr] > sz / 2) {` `                ``return` `get_centroid(nebr, ` `                                    ``node, sz);` `            ``}` `        ``}` `        ``return` `node;` `    ``}`   `    ``// Decompose the tree ` `    ``// into various centroids` `    ``void` `decompose(``int` `node, ``int` `par)` `    ``{` `        ``get_size(node, -1);`   `        ``// c is centroid of subtree 'node'` `        ``int` `c = get_centroid(node, par, ` `                             ``size[node]);`   `        ``// Find paths_originating_from 'c'` `        ``paths_originating_from(c);`   `        ``// Mark this centroid as removed` `        ``removed = ``true``;`   `        ``// Find other centroids` `        ``for` `(``auto` `nebr : g) {` `            ``if` `(!removed[nebr]) {` `                ``decompose(nebr, c);` `            ``}` `        ``}` `    ``}`   `    ``// This dfs is responsible for ` `    ``// calculating ans and ` `    ``// updating freq vector` `    ``void` `dfs(``int` `node, ``int` `par, ``int` `depth,` `             ``bool` `contri)` `    ``{` `        ``if` `(depth > k)` `            ``return``;` `        ``mx_depth = max(mx_depth, depth);`   `        ``if` `(contri) {` `            ``ans += freq[k - depth];` `        ``}` `        ``else` `{` `            ``freq[depth]++;` `        ``}`   `        ``for` `(``auto` `nebr : g[node]) {` `            ``if` `(nebr != par && ` `                ``!removed[nebr]) {` `                ``dfs(nebr, node, ` `                    ``depth + 1, contri);` `            ``}` `        ``}` `    ``}`   `    ``// Function to find K-length paths` `    ``// originating from node` `    ``void` `paths_originating_from(``int` `node)` `    ``{` `        ``mx_depth = 0;` `        ``freq[0] = 1;`   `        ``// For every not-removed nebr, ` `        ``// calculate its contribution, ` `        ``// then update freq vector for it` `        ``for` `(``auto` `nebr : g[node]) {` `            ``if` `(!removed[nebr]) {` `                ``dfs(nebr, node, 1, ``true``);` `                ``dfs(nebr, node, 1, ``false``);` `            ``}` `        ``}` `        `  `        ``// Re-initialize freq vector` `        ``for` `(``int` `i = 0; i <= mx_depth; ++i) {` `            ``freq[i] = 0;` `        ``}` `    ``}` `};`   `// Driver code` `int` `main()` `{` `    ``int` `N = 5, K = 2;`   `    ``CD cd_s(N, K);` `    ``cd_s.edge(1, 2);` `    ``cd_s.edge(1, 5);` `    ``cd_s.edge(2, 3);` `    ``cd_s.edge(2, 4);`   `    ``cd_s.decompose(0, -1);` `    ``cout << cd_s.ans;` `    ``return` `0;` `}`

## Java

 `// Java Code to implement above approach` `import` `java.util.*;`   `public` `class` `Solution ` `{` `  `  `    ``// Struct for centroid decomposition` `    ``static` `class` `CD` `    ``{` `      `  `        ``// 1. mx_depth will be used to store` `        ``// the height of a node` `        ``// 2. g[] is adjacency list for tree` `        ``// 3. freq[] stores frequency of nodes` `        ``// at particular height, it is maintained` `        ``// for children of a node` `        ``int` `n, k, mx_depth, ans;` `        ``boolean``[] removed;` `        ``int``[] size, freq;` `        ``ArrayList > g;`   `        ``// Constructor for struct` `        ``CD(``int` `n1, ``int` `k1)` `        ``{` `            ``n = n1;` `            ``k = k1;` `            ``ans = mx_depth = ``0``;`   `            ``g = ``new` `ArrayList<>();` `            ``for` `(``int` `i = ``0``; i < n; i++) {` `                ``g.add(``new` `ArrayList<>());` `            ``}` `            ``size = ``new` `int``[n];` `            ``freq = ``new` `int``[n];` `            ``removed = ``new` `boolean``[n];` `        ``}`   `        ``// Utility method to add edges to tree` `        ``public` `void` `edge(``int` `u, ``int` `v)` `        ``{` `            ``u--;` `            ``v--;` `            ``g.get(u).add(v);` `            ``g.get(v).add(u);` `        ``}`   `        ``// Finds size of a subtree,` `        ``// ignoring removed nodes in the way` `        ``public` `int` `get_size(``int` `node, ``int` `par)` `        ``{` `            ``if` `(removed[node])` `                ``return` `0``;` `            ``size[node] = ``1``;`   `            ``for` `(Integer nebr : g.get(node)) {` `                ``if` `(nebr != par) {` `                    ``size[node] += get_size(nebr, node);` `                ``}` `            ``}`   `            ``return` `size[node];` `        ``}`   `        ``// Calculates centroid of a subtree` `        ``// of 'node' of size 'sz'` `        ``int` `get_centroid(``int` `node, ``int` `par, ``int` `sz)` `        ``{` `            ``for` `(Integer nebr : g.get(node)) {` `                ``if` `(nebr != par && !removed[nebr]` `                    ``&& size[nebr] > sz / ``2``) {` `                    ``return` `get_centroid(nebr, node, sz);` `                ``}` `            ``}` `            ``return` `node;` `        ``}`   `        ``// Decompose the tree` `        ``// into various centroids` `        ``public` `void` `decompose(``int` `node, ``int` `par)` `        ``{` `            ``get_size(node, -``1``);`   `            ``// c is centroid of subtree 'node'` `            ``int` `c = get_centroid(node, par, size[node]);`   `            ``// Find paths_originating_from 'c'` `            ``paths_originating_from(c);`   `            ``// Mark this centroid as removed` `            ``removed = ``true``;`   `            ``// Find other centroids` `            ``for` `(Integer nebr : g.get(c)) {` `                ``if` `(!removed[nebr]) {` `                    ``decompose(nebr, c);` `                ``}` `            ``}` `        ``}`   `        ``// This dfs is responsible for` `        ``// calculating ans and` `        ``// updating freq vector` `        ``void` `dfs(``int` `node, ``int` `par, ``int` `depth,` `                 ``boolean` `contri)` `        ``{` `            ``if` `(depth > k)` `                ``return``;` `            ``mx_depth = Math.max(mx_depth, depth);`   `            ``if` `(contri) {` `                ``ans += freq[k - depth];` `            ``}` `            ``else` `{` `                ``freq[depth]++;` `            ``}`   `            ``for` `(Integer nebr : g.get(node)) {` `                ``if` `(nebr != par && !removed[nebr]) {` `                    ``dfs(nebr, node, depth + ``1``, contri);` `                ``}` `            ``}` `        ``}`   `        ``// Function to find K-length paths` `        ``// originating from node` `        ``void` `paths_originating_from(``int` `node)` `        ``{` `            ``mx_depth = ``0``;` `            ``freq[``0``] = ``1``;`   `            ``// For every not-removed nebr,` `            ``// calculate its contribution,` `            ``// then update freq vector for it` `            ``for` `(Integer nebr : g.get(node)) {` `                ``if` `(!removed[nebr]) {` `                    ``dfs(nebr, node, ``1``, ``true``);` `                    ``dfs(nebr, node, ``1``, ``false``);` `                ``}` `            ``}`   `            ``// Re-initialize freq vector` `            ``for` `(``int` `i = ``0``; i <= mx_depth; ++i) {` `                ``freq[i] = ``0``;` `            ``}` `        ``}` `    ``};`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `N = ``5``, K = ``2``;`   `        ``CD cd_s = ``new` `CD(N, K);` `        ``cd_s.edge(``1``, ``2``);` `        ``cd_s.edge(``1``, ``5``);` `        ``cd_s.edge(``2``, ``3``);` `        ``cd_s.edge(``2``, ``4``);`   `        ``cd_s.decompose(``0``, -``1``);` `        ``System.out.println(cd_s.ans);` `    ``}` `}`   `// This code is contributed by karandeep1234`

Output

`4`

Time Complexity: O(N * log(N)) where log N is the height of the tree
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Related Articles