Node whose removal minimizes the maximum size forest from an N-ary Tree
Last Updated :
20 May, 2021
Given an n-ary tree T, the task is to find a node whose removal minimizes the maximum size of all forests(connected components) generated.
Examples:
Input:
1
/ | \
2 3 4
/ \
5 6
Output: 1
Explanation:
There are six nodes which can be removed to form forests:
Remove(1): Largest Forest size is 3
Remove(2): Largest Forest size is 3
Remove(3): Largest Forest size is 5
Remove(4): Largest Forest size is 5
Remove(5): Largest Forest size is 5
Remove(6): Largest Forest size is 5
Therefore, removing either node 1 or 2 minimizes the maximum forest size to 3.
Input:
1
/ \
2 3
Output: 1
Explanation:
There are three nodes which can be removed to form forests:
Remove(1): Largest Forest size is 1
Remove(2): Largest Forest size is 1
Remove(3): Largest Forest size is 1
Therefore, removing either node 1 or 2 or 3 minimizes the maximum forest size to 1.
Approach: The idea is to traverse the tree using Depth First Search Traversal and for every node of the tree, count the number of nodes in its subtree. Removing any node from the given tree leads to two different types of forests:
- Connected components formed by the subtrees including its left and right child.
- Connected components formed by the subtree including its parent node
Therefore, follow the steps below to solve the problem:
- Traverse the tree using DFS.
- For every node, compute the number of nodes in its child subtrees recursively. Calculate the number of nodes in the connected component involving its parent by calculating the difference of the total number of nodes in the given tree and the sum of nodes in its child subtrees.
- Keep updating minimum of the maximum size of connected components obtained for any node.
- Finally, print the node corresponding to which the minimum of the maximum size of connected components is obtained.
Below is the implementation of the above approach:
C++
// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
int mini = 105, ans, n;
vector<vector<int> > g(100);
int size[100];
// Function to create the graph
void create_graph()
{
g[1].push_back(2);
g[2].push_back(1);
g[1].push_back(3);
g[3].push_back(1);
g[1].push_back(4);
g[4].push_back(1);
g[2].push_back(5);
g[5].push_back(2);
g[2].push_back(6);
g[6].push_back(2);
}
// Function to traverse the graph
// and find the minimum of maximum
// size forest after removing a node
void dfs(int node, int parent)
{
size[node] = 1;
int mx = 0;
// Traversing every child subtree
// except the parent node
for (int y : g[node]) {
if (y == parent)
continue;
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the maximum
// size of forests
mx = max(mx, size[y]);
}
// Update the minimum of maximum
// size of forests obtained
mx = max(mx, n - size[node]);
// Condition to find the minimum
// of maximum size forest
if (mx < mini) {
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
int main()
{
n = 6;
create_graph();
dfs(1, -1);
cout << ans << "\n";
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
static int mini = 105, ans, n;
static Vector<Integer> []g = new Vector[100];
static int []size = new int[100];
// Function to create the graph
static void create_graph()
{
g[1].add(2);
g[2].add(1);
g[1].add(3);
g[3].add(1);
g[1].add(4);
g[4].add(1);
g[2].add(5);
g[5].add(2);
g[2].add(6);
g[6].add(2);
}
// Function to traverse the graph
// and find the minimum of maximum
// size forest after removing a node
static void dfs(int node, int parent)
{
size[node] = 1;
int mx = 0;
// Traversing every child subtree
// except the parent node
for (int y : g[node])
{
if (y == parent)
continue;
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the maximum
// size of forests
mx = Math.max(mx, size[y]);
}
// Update the minimum of maximum
// size of forests obtained
mx = Math.max(mx, n - size[node]);
// Condition to find the minimum
// of maximum size forest
if (mx < mini)
{
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
public static void main(String[] args)
{
n = 6;
for (int i = 0; i < g.length; i++)
g[i] = new Vector<Integer>();
create_graph();
dfs(1, -1);
System.out.print(ans + "\n");
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program to implement
# the above approach
mini = 105;
ans = 0;
n = 0;
g = [];
size = [0] * 100;
# Function to create the graph
def create_graph():
g[1].append(2);
g[2].append(1);
g[1].append(3);
g[3].append(1);
g[1].append(4);
g[4].append(1);
g[2].append(5);
g[5].append(2);
g[2].append(6);
g[6].append(2);
# Function to traverse the graph
# and find the minimum of maximum
# size forest after removing a Node
def dfs(Node, parent):
size[Node] = 1;
mx = 0;
global mini
global ans
# Traversing every child subtree
# except the parent Node
for y in g[Node]:
if (y == parent):
continue;
# Traverse all subtrees
dfs(y, Node);
size[Node] += size[y];
# Update the maximum
# size of forests
mx = max(mx, size[y]);
# Update the minimum of maximum
# size of forests obtained
mx = max(mx, n - size[Node]);
# Condition to find the minimum
# of maximum size forest
if (mx < mini):
mini = mx;
# Update and store the
# corresponding Node
ans = Node;
# Driver Code
if __name__ == '__main__':
n = 6;
for i in range(100):
g.append([])
create_graph();
dfs(1, -1);
print(ans);
# This code is contributed by 29AjayKumar
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
static int mini = 105, ans, n;
static List<int> []g = new List<int>[100];
static int []size = new int[100];
// Function to create the graph
static void create_graph()
{
g[1].Add(2);
g[2].Add(1);
g[1].Add(3);
g[3].Add(1);
g[1].Add(4);
g[4].Add(1);
g[2].Add(5);
g[5].Add(2);
g[2].Add(6);
g[6].Add(2);
}
// Function to traverse the graph
// and find the minimum of maximum
// size forest after removing a node
static void dfs(int node, int parent)
{
size[node] = 1;
int mx = 0;
// Traversing every child subtree
// except the parent node
foreach (int y in g[node])
{
if (y == parent)
continue;
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the maximum
// size of forests
mx = Math.Max(mx, size[y]);
}
// Update the minimum of maximum
// size of forests obtained
mx = Math.Max(mx, n - size[node]);
// Condition to find the minimum
// of maximum size forest
if (mx < mini)
{
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
public static void Main(String[] args)
{
n = 6;
for (int i = 0; i < g.Length; i++)
g[i] = new List<int>();
create_graph();
dfs(1, -1);
Console.Write(ans + "\n");
}
}
// This code is contributed by gauravrajput1
JavaScript
<script>
// JavaScript program to implement
// the above approach
var mini = 105, ans, n;
var g = Array.from(Array(100), ()=> new Array());
var size = Array(100).fill(0);
// Function to create the graph
function create_graph()
{
g[1].push(2);
g[2].push(1);
g[1].push(3);
g[3].push(1);
g[1].push(4);
g[4].push(1);
g[2].push(5);
g[5].push(2);
g[2].push(6);
g[6].push(2);
}
// Function to traverse the graph
// and find the minimum of Math.maximum
// size forest after removing a node
function dfs(node, parent)
{
size[node] = 1;
var mx = 0;
// Traversing every child subtree
// except the parent node
g[node].forEach(y => {
if (y != parent)
{
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the Math.maximum
// size of forests
mx = Math.max(mx, size[y]);
}
});
// Update the minimum of Math.maximum
// size of forests obtained
mx = Math.max(mx, n - size[node]);
// Condition to find the minimum
// of Math.maximum size forest
if (mx < mini) {
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
n = 6;
create_graph();
dfs(1, -1);
document.write( ans );
</script>
Time Complexity: O(N), where N is the number of nodes.
Auxiliary Space: O(N)
Similar Reads
Maximum edge removal from tree to make even forest Given a tree with n nodes where n is even. The tree is numbered from 1 to n, has n - 1 edges and is rooted at node 1. The task is to eliminate the maximum number of edges resulting in a set of disjoint trees where the number of nodes in each tree is divisible by 2.Examples: Input: n = 10, edges = [[
8 min read
Maximize sum of path from the Root to a Leaf node in N-ary Tree Given a generic tree consisting of n nodes, the task is to find the maximum sum of the path from the root to the leaf node.Examples:Input:Output: 12Explanation: The path sum to every leaf from the root are:For node 4: 1 -> 2 -> 4 = 7For node 5: 1 -> 2 -> 5 = 8For node 6: 1 -> 3 ->
5 min read
Minimum valued node having maximum depth in an N-ary Tree Given a tree of N nodes, the task is to find the node having maximum depth starting from the root node, taking the root node at zero depth. If there are more than 1 maximum depth node, then find the one having the smallest value. Examples: Input: 1 / \ 2 3 / \ 4 5 Output: 4 Explanation: For this tre
5 min read
Size of the Largest Trees in a Forest formed by the given Graph Given an undirected acyclic graph having N nodes and M edges, the task is to find the size of the largest tree in the forest formed by the graph. A forest is a collection of disjoint trees. In other words, we can also say that forest is a collection of an acyclic graph which is not connected. Exampl
8 min read
Remove all leaf nodes from a Generic Tree or N-ary Tree Given an n-ary tree containing positive node values, the task is to delete all the leaf nodes from the tree and print preorder traversal of the tree after performing the deletion.Note: An n-ary tree is a tree where each node can have zero or more children nodes. Unlike a binary tree, which has at mo
6 min read