Roots of a tree which give minimum height - GeeksforGeeks

25 Jan, 2022
Given an undirected graph, which has tree characteristics. It is possible to choose any node as root, the task is to find those nodes only which minimize the height of tree. 
Example: In below diagram all node are made as root one by one, we can see that when 3 and 4 are root, height of tree is minimum(2) so {3, 4} is our answer.  
 
We can solve this problem by first thinking about the 1-D solution, that is if the longest graph is given, then the node which will minimize the height will be mid node if total node count is odd or mid-two-node if total node count is even. This solution can be reached by the following approach – Start two pointers from both ends of the path and move one step each time until pointers meet or one step away, at the end pointers will be at those nodes which will minimize the height because we have divided the nodes evenly so the height will be minimum. The same approach can be applied to a general tree also. Start pointers from all leaf nodes and move one step inside each time, keep combining pointers which overlap while moving, at the end only one pointer will remain on some vertex or two pointers will remain at one distance away. Those nodes represent the root of the vertex which will minimize the height of the tree. So we can have only one root or at max two roots for minimum height depending on tree structure as explained above. For the implementation we will not use actual pointers instead we’ll follow BFS like approach, In starting all leaf node are pushed into the queue, then they are removed from the tree, next new leaf node is pushed in the queue, this procedure keeps on going until we have only 1 or 2 node in our tree, which represent the result.  
C++
Python3
//  C++ program to find root which gives minimum height to tree#include <bits/stdc++.h>using namespace std; // This class represents a undirected graph using adjacency list// representationclass Graph{public:    int V; // No. of vertices     // Pointer to an array containing adjacency lists    list<int> *adj;     // Vector which stores degree of all vertices    vector<int> degree;     Graph(int V);            // Constructor    void addEdge(int v, int w);   // To add an edge     // function to get roots which give minimum height    vector<int> rootForMinimumHeight();}; // Constructor of graph, initializes adjacency list and// degree vectorGraph::Graph(int V){    this->V = V;    adj = new list<int>[V];    for (int i = 0; i < V; i++)        degree.push_back(0);} // addEdge method adds vertex to adjacency list and increases// degree by 1void Graph::addEdge(int v, int w){    adj[v].push_back(w);    // Add w to v’s list    adj[w].push_back(v);    // Add v to w’s list    degree[v]++;            // increment degree of v by 1    degree[w]++;            // increment degree of w by 1} //  Method to return roots which gives minimum height to treevector<int> Graph::rootForMinimumHeight(){    queue<int> q;     //  first enqueue all leaf nodes in queue    for (int i = 0; i < V; i++)        if (degree[i] == 1)            q.push(i);     //  loop until total vertex remains less than 2    while (V > 2)    {        int popEle = q.size();        V -= popEle;      // popEle number of vertices will be popped                 for (int i = 0; i < popEle; i++)        {            int t = q.front();            q.pop();             // for each neighbour, decrease its degree and            // if it become leaf, insert into queue            for (auto j = adj[t].begin(); j != adj[t].end(); j++)            {                degree[*j]--;                if (degree[*j] == 1)                    q.push(*j);            }        }    }     //  copying the result from queue to result vector    vector<int> res;    while (!q.empty())    {        res.push_back(q.front());        q.pop();    }    return res;}  //  Driver codeint main(){    Graph g(6);    g.addEdge(0, 3);    g.addEdge(1, 3);    g.addEdge(2, 3);    g.addEdge(4, 3);    g.addEdge(5, 4);       // Function Call    vector<int> res = g.rootForMinimumHeight();    for (int i = 0; i < res.size(); i++)        cout << res[i] << " ";    cout << endl;}
# Python program to find root which gives minimum# height to tree # This class represents a undirected graph using# adjacency list representation  class Graph:     # Constructor of graph, initialize adjacency list    # and degree vector    def __init__(self, V, addEdge, rootForMinimumHeight):        self.V = V        self.adj = dict((i, []) for i in range(V))        self.degree = list()        for i in range(V):            self.degree.append(0)         # The below lines allows us define methods outside        # of class definition        # Check http://bit.ly/2e5HfrW for better explanation        Graph.addEdge = addEdge        Graph.rootForMinimumHeight = rootForMinimumHeight  # addEdge method adds vertex to adjacency list and# increases degree by 1def addEdge(self, v, w):    self.adj[v].append(w)  # Adds w to v's list    self.adj[w].append(v)  # Adds v to w's list    self.degree[v] += 1      # increment degree of v by 1    self.degree[w] += 1      # increment degree of w by 1  # Method to return roots which gives minimum height to treedef rootForMinimumHeight(self):     from queue import Queue    q = Queue()     # First enqueue all leaf nodes in queue    for i in range(self.V):        if self.degree[i] == 1:            q.put(i)     # loop until total vertex remains less than 2    while(self.V > 2):        p = q.qsize()        self.V -= p        for i in range(p):            t = q.get()             # for each neighbour, decrease its degree and            # if it become leaf, insert into queue            for j in self.adj[t]:                self.degree[j] -= 1                if self.degree[j] == 1:                    q.put(j)     #  Copying the result from queue to result vector    res = list()    while(q.qsize() > 0):        res.append(q.get())     return res  # Driver codeg = Graph(6, addEdge, rootForMinimumHeight)g.addEdge(0, 3)g.addEdge(1, 3)g.addEdge(2, 3)g.addEdge(4, 3)g.addEdge(5, 4) # Function callres = g.rootForMinimumHeight()for i in res:    print (i,end=" ") # This code is contributed by Nikhil Kumar Singh(nickzuck_007)
3 4 
As we are accessing each node once, the total time complexity of the solution is O(n).
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
ankur1999
adnanirshad158
amartyaghoshgfg
Graph
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Topological Sorting
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Detect Cycle in a Directed Graph
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Ford-Fulkerson Algorithm for Maximum Flow Problem
Disjoint Set (Or Union-Find) | Set 1 (Detect Cycle in an Undirected Graph)
Traveling Salesman Problem (TSP) Implementation
Detect cycle in an undirected graph