Diameters for each node of Tree after connecting it with given disconnected component
Given a Tree having N nodes connected by N − 1 edge and a single disconnected node, the task is to find the diameters for each node of the given Tree after connecting it with the given disconnected component.
Example:
Input:
Output: 3 3 4 4 4 4
Explanation:
Initially diameter of tree = 3.
If an edge is added between node 1 and node 7, then the diameter of the tree is equal to 3(7 -> 1 -> 2 -> 5).
If an edge is added between node 2 and node 7, then the diameter of the tree is equal to 3(3 -> 1 -> 2 -> 5).
If an edge is added between node 3 and node 7, then the diameter of the tree is equal to 4(7 -> 3 -> 1 -> 2 -> 5).
If an edge is added between node 4 and node 7, then the diameter of the new tree is equal to 4(7-> 4 -> 2 -> 1 -> 3).
If an edge is added between node 5 and node 7, then the diameter of the new tree will be 4(7-> 5 -> 2 -> 1 -> 3).
If an edge is added between node 6 and node 7, then the diameter of the new tree will be 4((7-> 6 -> 2 -> 1 -> 3)).
Input:
Output: 3 2 3
Explanation:
Initial diameter of the tree = 2
If an edge is added between node 1 and node 4, then the diameter of the tree is equal to 3(4 -> 1 -> 2 -> 3).
If an edge is added between node 2 and node 4, then the diameter of the tree is equal to 2(4 -> 2 -> 3).
If an edge is added between node 3 and node 4, then the diameter of the tree is equal to 3(4 -> 3 -> 2 -> 1).
Approach: To solve the problem, the following observations need to be made:
- The diameter increases by 1 when the disconnected node is connected to an edge which forms the end of the diameter.
- For all other nodes, the diameter remains unchanged on connecting the disconnected node.
Follow the steps given below to solve the problem based on the above observations:
- Perform the DFS traversal of the given tree.
- While traversing, keep track of the farthest distance traveled and the farthest node.
- Now, perform DFS from the farthest node obtained from the above step and keep track of the farthest node from this node.
- Now, perform DFS and keep adding nodes in a Map that is farthest from the two nodes obtained from the above steps separately.
Below is the implementation of the above approach:
C++
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std; // Keeps track of the farthest // end of the diameter int X = 1; // Keeps track of the length of // the diameter int diameter = 0; // Stores the nodes which are at // ends of the diameter map< int , bool > mp; // Perform DFS on the given tree void dfs( int current_node, int prev_node, int len, bool add_to_map, vector<vector< int > >& adj) { // Update diameter and X if (len > diameter) { diameter = len; X = current_node; } // If current node is an end of diameter if (add_to_map && len == diameter) { mp[current_node] = 1; } // Traverse its neighbors for ( auto & it : adj[current_node]) { if (it != prev_node) dfs(it, current_node, len + 1, add_to_map, adj); } } // Function to call DFS for the // required purposes void dfsUtility(vector<vector< int > >& adj) { // DFS from a random node and find // the node farthest from it dfs(1, -1, 0, 0, adj); int farthest_node = X; // DFS from X to calculate diameter dfs(farthest_node, -1, 0, 0, adj); // DFS from farthest_node to find // the farthest node(s) from it dfs(farthest_node, -1, 0, 1, adj); // DFS from X (other end of diameter) and // check the farthest node(s) from it dfs(X, -1, 0, 1, adj); } void printDiameters(vector<vector< int > >& adj) { dfsUtility(adj); for ( int i = 1; i <= 6; i++) { // If node i is the end of // a diameter if (mp[i] == 1) // Increase diameter by 1 cout << diameter + 1 << ", " ; // Otherwise else // Remains unchanged cout << diameter << ", " ; } } // Driver Code int main() { /* constructed tree is 1 / \ 2 3 7 /|\ / | \ 4 5 6 */ vector<vector< int > > adj(7); // creating undirected edges adj[1].push_back(2); adj[2].push_back(1); adj[1].push_back(3); adj[3].push_back(1); adj[2].push_back(4); adj[4].push_back(2); adj[2].push_back(5); adj[5].push_back(2); adj[2].push_back(6); adj[6].push_back(2); printDiameters(adj); return 0; } |
Java
// Java Program to implement // the above approach import java.util.*; class GFG{ // Keeps track of the farthest // end of the diameter static int X = 1 ; // Keeps track of the length of // the diameter static int diameter = 0 ; // Stores the nodes which are at // ends of the diameter static HashMap<Integer, Boolean> mp = new HashMap<>(); // Perform DFS on the given tree static void dfs( int current_node, int prev_node, int len, boolean add_to_map, Vector<Integer> [] adj) { // Update diameter and X if (len > diameter) { diameter = len; X = current_node; } // If current node is an end of diameter if (add_to_map && len == diameter) { mp.put(current_node, true ); } // Traverse its neighbors for ( int it : adj[current_node]) { if (it != prev_node) dfs(it, current_node, len + 1 , add_to_map, adj); } } // Function to call DFS for the // required purposes static void dfsUtility(Vector<Integer> [] adj) { // DFS from a random node and find // the node farthest from it dfs( 1 , - 1 , 0 , false , adj); int farthest_node = X; // DFS from X to calculate diameter dfs(farthest_node, - 1 , 0 , false , adj); // DFS from farthest_node to find // the farthest node(s) from it dfs(farthest_node, - 1 , 0 , true , adj); // DFS from X (other end of diameter) and // check the farthest node(s) from it dfs(X, - 1 , 0 , true , adj); } static void printDiameters(Vector<Integer> [] adj) { dfsUtility(adj); for ( int i = 1 ; i <= 6 ; i++) { // If node i is the end of // a diameter if (mp.containsKey(i) && mp.get(i) == true ) // Increase diameter by 1 System.out.print(diameter + 1 + ", " ); // Otherwise else // Remains unchanged System.out.print(diameter + ", " ); } } // Driver Code public static void main(String[] args) { /* constructed tree is 1 / \ 2 3 7 /|\ / | \ 4 5 6 */ Vector<Integer> []adj = new Vector[ 7 ]; for ( int i = 0 ; i < adj.length; i++) adj[i] = new Vector<Integer>(); // creating undirected edges adj[ 1 ].add( 2 ); adj[ 2 ].add( 1 ); adj[ 1 ].add( 3 ); adj[ 3 ].add( 1 ); adj[ 2 ].add( 4 ); adj[ 4 ].add( 2 ); adj[ 2 ].add( 5 ); adj[ 5 ].add( 2 ); adj[ 2 ].add( 6 ); adj[ 6 ].add( 2 ); printDiameters(adj); } } // This code is contributed by PrinciRaj1992 |
Python3
# Python3 program to implement # the above approach from collections import defaultdict # Keeps track of the farthest # end of the diameter X = 1 # Keeps track of the length of # the diameter diameter = 0 # Stores the nodes which are at # ends of the diameter mp = defaultdict( lambda : 0 ) # Perform DFS on the given tree def dfs(current_node, prev_node, len , add_to_map, adj): global diameter, X # Update diameter and X if len > diameter: diameter = len X = current_node # If current node is an end of diameter if add_to_map and len = = diameter: mp[current_node] = 1 # Traverse its neighbors for it in adj[current_node]: if it ! = prev_node: dfs(it, current_node, len + 1 , add_to_map, adj) # Function to call DFS for the # required purposes def dfsUtility(adj): # DFS from a random node and find # the node farthest from it dfs( 1 , - 1 , 0 , 0 , adj) farthest_node = X # DFS from X to calculate diameter dfs(farthest_node, - 1 , 0 , 0 , adj) # DFS from farthest_node to find # the farthest node(s) from it dfs(farthest_node, - 1 , 0 , 1 , adj) # DFS from X (other end of diameter) and # check the farthest node(s) from it dfs(X, - 1 , 0 , 1 , adj) def printDiameters(adj): global diameter dfsUtility(adj) for i in range ( 1 , 6 + 1 ): # If node i is the end of # a diameter if mp[i] = = 1 : # Increase diameter by 1 print (diameter + 1 , end = ", " ) # Otherwise else : # Remains unchanged print (diameter, end = ", " ) # Driver code # constructed tree is # 1 # / \ # 2 3 # / | \ # 4 5 6 # | # 7 adj = [] for i in range ( 7 ): adj.append([]) # Creating undirected edges adj[ 1 ].append( 2 ) adj[ 2 ].append( 1 ) adj[ 1 ].append( 3 ) adj[ 3 ].append( 1 ) adj[ 2 ].append( 4 ) adj[ 4 ].append( 2 ) adj[ 2 ].append( 5 ) adj[ 5 ].append( 2 ) adj[ 2 ].append( 6 ) adj[ 6 ].append( 2 ) printDiameters(adj) # This code is contributed by Stuti Pathak |
C#
// C# Program to implement // the above approach using System; using System.Collections.Generic; class GFG { // Keeps track of the farthest // end of the diameter static int X = 1; // Keeps track of the // length of the diameter static int diameter = 0; // Stores the nodes which are at // ends of the diameter static Dictionary< int , Boolean> mp = new Dictionary< int , Boolean>(); // Perform DFS on the given tree static void dfs( int current_node, int prev_node, int len, bool add_to_map, List< int >[] adj) { // Update diameter and X if (len > diameter) { diameter = len; X = current_node; } // If current node is an end of diameter if (add_to_map && len == diameter) { mp.Add(current_node, true ); } // Traverse its neighbors foreach ( int it in adj[current_node]) { if (it != prev_node) dfs(it, current_node, len + 1, add_to_map, adj); } } // Function to call DFS for // the required purposes static void dfsUtility(List< int >[] adj) { // DFS from a random node and find // the node farthest from it dfs(1, -1, 0, false , adj); int farthest_node = X; // DFS from X to calculate diameter dfs(farthest_node, -1, 0, false , adj); // DFS from farthest_node to find // the farthest node(s) from it dfs(farthest_node, -1, 0, true , adj); // DFS from X (other end of diameter) and // check the farthest node(s) from it dfs(X, -1, 0, true , adj); } static void printDiameters(List< int >[] adj) { dfsUtility(adj); for ( int i = 1; i <= 6; i++) { // If node i is the end // of a diameter if (mp.ContainsKey(i) && mp[i] == true ) // Increase diameter by 1 Console.Write(diameter + 1 + ", " ); // Otherwise else // Remains unchanged Console.Write(diameter + ", " ); } } // Driver Code public static void Main(String[] args) { /* constructed tree is 1 / \ 2 3 7 /|\ / | \ 4 5 6 */ List< int >[] adj = new List< int >[ 7 ]; for ( int i = 0; i < adj.Length; i++) adj[i] = new List< int >(); // creating undirected edges adj[1].Add(2); adj[2].Add(1); adj[1].Add(3); adj[3].Add(1); adj[2].Add(4); adj[4].Add(2); adj[2].Add(5); adj[5].Add(2); adj[2].Add(6); adj[6].Add(2); printDiameters(adj); } } // This code is contributed by Amit Katiyar |
Javascript
<script> // Javascript program for the above approach // Keeps track of the farthest // end of the diameter let X = 1; // Keeps track of the // length of the diameter let diameter = 0; // Stores the nodes which are at // ends of the diameter let mp = new Map(); // Perform DFS on the given tree function dfs(current_node, prev_node, len, add_to_map, adj) { // Update diameter and X if (len > diameter) { diameter = len; X = current_node; } // If current node is an end of diameter if (add_to_map && len == diameter) { mp.set(current_node, true ); } // Traverse its neighbors for (let it = 0; it < adj[current_node].length; it++) { if (adj[current_node][it] != prev_node) dfs(adj[current_node][it], current_node, len + 1, add_to_map, adj); } } // Function to call DFS for // the required purposes function dfsUtility(adj) { // DFS from a random node and find // the node farthest from it dfs(1, -1, 0, false , adj); let farthest_node = X; // DFS from X to calculate diameter dfs(farthest_node, -1, 0, false , adj); // DFS from farthest_node to find // the farthest node(s) from it dfs(farthest_node, -1, 0, true , adj); // DFS from X (other end of diameter) and // check the farthest node(s) from it dfs(X, -1, 0, true , adj); } function printDiameters(adj) { dfsUtility(adj); for (let i = 1; i <= 6; i++) { // If node i is the end // of a diameter if (mp.has(i) && mp.get(i) == true ) // Increase diameter by 1 document.write(diameter + 1 + ", " ); // Otherwise else // Remains unchanged document.write(diameter + ", " ); } } /* constructed tree is 1 / \ 2 3 7 /|\ / | \ 4 5 6 */ let adj = new Array(7); for (let i = 0; i < adj.length; i++) adj[i] = []; // creating undirected edges adj[1].push(2); adj[2].push(1); adj[1].push(3); adj[3].push(1); adj[2].push(4); adj[4].push(2); adj[2].push(5); adj[5].push(2); adj[2].push(6); adj[6].push(2); printDiameters(adj); </script> |
3, 3, 4, 4, 4, 4,
Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges in the graph.
Auxiliary Space: O(V)
Please Login to comment...