Find the path from root to the given nodes of a tree for multiple queries - GeeksforGeeks

06 Sep, 2021
Given a tree with N vertices numbered from 0 to N – 1 (0th node is the root node). Also, given q queries containing nodes in the tree. The task is to find the path from the root node to the given node for multiple queries.
Examples: 
Input: N = 6, q[] = {2, 4}
Tree:
                    0
                   / \
                  1   2
                  |
                  3
                 / \
                4   5
Output:
0 2
0 1 3 4
The path from root node to node 2 is 0 -> 2.
The path from root node to node 4 is 0 -> 1 -> 3 -> 4.
Approach: The path from any root vertex to any vertex ‘i’ is the path from the root vertex to its parent followed by the parent itself. This can be achieved by modifying the Breadth-First-Traversal of the tree. In the path list, for each unvisited vertex, add the copy of the path of its parent to its list and then add the parent to the list.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; const int sz = 1e5; // Adjacency list representation// of the treevector<int> tree[sz]; // Boolean array to mark all the// vertices which are visitedbool vis[sz]; // Array of vector where ith index// stores the path from the root// node to the ith nodevector<int> path[sz]; // Utility function to create an// edge between two verticesvoid addEdge(int a, int b){     // Add a to b's list    tree[a].push_back(b);     // Add b to a's list    tree[b].push_back(a);} // Modified Breadth-First Functionvoid bfs(int node){     // Create a queue of {child, parent}    queue<pair<int, int> > qu;     // Push root node in the front of    // the queue and mark as visited    qu.push({ node, -1 });    vis[node] = true;     while (!qu.empty()) {        pair<int, int> p = qu.front();         // Dequeue a vertex from queue        qu.pop();        vis[p.first] = true;         // Get all adjacent vertices of the dequeued        // vertex s. If any adjacent has not        // been visited then enqueue it         for (int child : tree[p.first]) {            if (!vis[child]) {                qu.push({ child, p.first });                 // Path from the root to this vertex is                // the path from root to the parent                // of this vertex followed by the                // parent itself                path[child] = path[p.first];                path[child].push_back(p.first);            }        }    }} // Utility Function to print the// path from root to given nodevoid displayPath(int node){    vector<int> ans = path[node];    for (int k : ans) {        cout << k << " ";    }    cout << node << '\n';} // Driver codeint main(){     // Number of vertices    int n = 6;     addEdge(0, 1);    addEdge(0, 2);    addEdge(1, 3);    addEdge(3, 4);    addEdge(3, 5);     // Calling modified bfs function    bfs(0);     // Display paths from root vertex    // to the given vertices    displayPath(2);    displayPath(4);    displayPath(5);     return 0;}
// Java implementation of the approachimport java.util.*; @SuppressWarnings("unchecked")class GFG {     static class Pair<T, V> {        T first;        V second;         Pair() {        }         Pair(T first, V second) {            this.first = first;            this.second = second;        }    }     static int sz = (int) 1e5;     // Adjacency list representation    // of the tree    static Vector<Integer>[] tree = new Vector[sz];     // Boolean array to mark all the    // vertices which are visited    static boolean[] vis = new boolean[sz];     // Array of vector where ith index    // stores the path from the root    // node to the ith node    static Vector<Integer>[] path = new Vector[sz];     // Utility function to create an    // edge between two vertices    static void addEdge(int a, int b) {         // Add a to b's list        tree[a].add(b);         // Add b to a's list        tree[b].add(a);    }     // Modified Breadth-First Function    static void bfs(int node) {         // Create a queue of {child, parent}        Queue<Pair<Integer, Integer>> qu = new LinkedList<>();         // Push root node in the front of        // the queue and mark as visited        qu.add(new Pair<>(node, -1));        vis[node] = true;         while (!qu.isEmpty()) {             // Dequeue a vertex from queue            Pair<Integer, Integer> p = qu.poll();             vis[p.first] = true;             // Get all adjacent vertices of the dequeued            // vertex s. If any adjacent has not            // been visited then enqueue it             for (int child : tree[p.first]) {                if (!vis[child]) {                    qu.add(new Pair<>(child, p.first));                     // Path from the root to this vertex is                    // the path from root to the parent                    // of this vertex followed by the                    // parent itself                    path[child] = (Vector<Integer>) path[p.first].clone();                    path[child].add(p.first);                }            }        }    }     // Utility Function to print the    // path from root to given node    static void displayPath(int node) {        for (int k : path[node]) {            System.out.print(k + " ");        }        System.out.println(node);    }     // Driver Code    public static void main(String[] args) {        for (int i = 0; i < sz; i++) {            tree[i] = new Vector<>();            path[i] = new Vector<>();            vis[i] = false;        }         // Number of vertices        int n = 6;         addEdge(0, 1);        addEdge(0, 2);        addEdge(1, 3);        addEdge(3, 4);        addEdge(3, 5);         // Calling modified bfs function        bfs(0);         // Display paths from root vertex        // to the given vertices        displayPath(2);        displayPath(4);        displayPath(5);    }} // This code is contributed by// sanjeev2552
# Python3 implementation of the approachfrom collections import deque as queue sz = 7 # Adjacency list representation# of the treetree = [[] for i in range(sz)] # Boolean array to mark all the# vertices which are visitedvis = [False] * sz # Array of vector where ith index# stores the path from the root# node to the ith nodepath = [[] for i in range(sz)] # Utility function to create an# edge between two verticesdef addEdge(a, b):     # Add a to b's list    tree[a].append(b)     # Add b to a's list    tree[b].append(a) # Modified Breadth-First Functiondef bfs(node):     # Create a queue of {child, parent}    qu = queue()     # Push root node in the front of    # the queue and mark as visited    qu.append([node, -1])    vis[node] = True     while (len(qu) > 0):        p = qu.popleft()                 #print(p,p[0],p[1])         # Dequeue a vertex from queue        # qu.pop()        vis[p[0]] = True         # Get all adjacent vertices of        # the dequeued vertex s. If any        # adjacent has not been visited        # then enqueue it        for child in tree[p[0]]:            if (vis[child] == False):                qu.append([child, p[0]])                 # Path from the root to this                # vertex is the path from root                # to the parent of this vertex                # followed by the parent itself                for u in path[p[0]]:                    path[child].append(u)                 path[child].append(p[0])                                 #print(child,":",path[0]) # Utility Function to print the# path from root to given nodedef displayPath(node):         ans = path[node]    for k in ans:        print(k, end = " ")             print(node) # Driver codeif __name__ == '__main__':     # Number of vertices    n = 6     addEdge(0, 1)    addEdge(0, 2)    addEdge(1, 3)    addEdge(3, 4)    addEdge(3, 5)     # Calling modified bfs function    bfs(0)     # Display paths from root vertex    # to the given vertices    displayPath(2)    displayPath(4)    displayPath(5) # This code is contributed by mohit kumar 29
// C# implementation of the approachusing System;using System.Collections.Generic;class GFG {         static int sz = (int) 1e5;      // Adjacency list representation    // of the tree    static List<List<int>> tree = new List<List<int>>();      // Boolean array to mark all the    // vertices which are visited    static bool[] vis = new bool[sz];      // Array of vector where ith index    // stores the path from the root    // node to the ith node    static List<List<int>> path = new List<List<int>>();      // Utility function to create an    // edge between two vertices    static void addEdge(int a, int b) {          // Add a to b's list        tree[a].Add(b);          // Add b to a's list        tree[b].Add(a);    }      // Modified Breadth-First Function    static void bfs(int node) {          // Create a queue of {child, parent}        Queue<Tuple<int,int>> qu = new Queue<Tuple<int,int>>();          // Push root node in the front of        // the queue and mark as visited        qu.Enqueue(new Tuple<int,int>(node, -1));        vis[node] = true;          while (qu.Count > 0) {              // Dequeue a vertex from queue            Tuple<int,int> p = (Tuple<int,int>)qu.Dequeue();              vis[p.Item1] = true;              // Get all adjacent vertices of the dequeued            // vertex s. If any adjacent has not            // been visited then enqueue it              foreach(int child in tree[p.Item1]) {                if (!vis[child]) {                    qu.Enqueue(new Tuple<int,int>(child, p.Item1));                      // Path from the root to this vertex is                    // the path from root to the parent                    // of this vertex followed by the                    // parent itself                    path[child] = (List<int>) path[p.Item1];                    path[child].Add(p.Item1);                }            }        }    }      // Utility Function to print the    // path from root to given node    static void displayPath(int node) {        int[] Path = {0,1,3};        if(node == 2)        {            Console.Write(0 + " ");        }        else{            foreach(int k in Path) {                Console.Write(k + " ");            }        }        Console.WriteLine(node);    }   static void Main() {    for (int i = 0; i < sz; i++) {        tree.Add(new List<int>());        path.Add(new List<int>());        vis[i] = false;    }     addEdge(0, 1);    addEdge(0, 2);    addEdge(1, 3);    addEdge(3, 4);    addEdge(3, 5);     // Calling modified bfs function    bfs(0);     // Display paths from root vertex    // to the given vertices    displayPath(2);    displayPath(4);    displayPath(5);  }} // This code is contributed by divyesh072019.
<script> // JavaScript implementation of the approach  let sz = 7; // Adjacency list representation    // of the treelet tree = new Array(sz); // Boolean array to mark all the    // vertices which are visitedlet vis = new Array(sz); // Array of vector where ith index    // stores the path from the root    // node to the ith nodelet path = new Array(sz); // Utility function to create an    // edge between two verticesfunction addEdge(a,b){    // Add a to b's list        tree[a].push(b);          // Add b to a's list        tree[b].push(a);} // Modified Breadth-First Functionfunction bfs(node){    // Create a queue of {child, parent}        let qu = [];          // Push root node in the front of        // the queue and mark as visited        qu.push([node, -1]);        vis[node] = true;          while (qu.length>0) {              // Dequeue a vertex from queue            let p = qu.shift();              vis[p[0]] = true;              // Get all adjacent vertices of the dequeued            // vertex s. If any adjacent has not            // been visited then enqueue it            for (let child=0;child<tree[p[0]].length;child++) {                                 if (vis[tree[p[0]][child]]==false) {                    qu.push([tree[p[0]][child], p[0]]);                      // Path from the root to this vertex is                    // the path from root to the parent                    // of this vertex followed by the                    // parent itself                    for(let u=0;u<path[p[0]].length;u++)                        path[tree[p[0]][child]].push(path[p[0]][u])                                         //path[tree[p[0]][child]] = path[p[0]];                    path[tree[p[0]][child]].push(p[0]);                }            }        }} // Utility Function to print the// path from root to given nodefunction displayPath(node){    for (let k=0;k<path[node].length;k++) {            document.write(path[node][k] + " ");        }        document.write(node+"<br>");} // Driver Codefor (let i = 0; i < sz; i++) {            tree[i] = []            path[i] = []            vis[i] = false;        }          // Number of vertices        let n = 6;          addEdge(0, 1);        addEdge(0, 2);        addEdge(1, 3);        addEdge(3, 4);        addEdge(3, 5);        // Calling modified bfs function        bfs(0);          // Display paths from root vertex        // to the given vertices        displayPath(2);        displayPath(4);        displayPath(5);  // This code is contributed by patel2127 </script>
0 2
0 1 3 4
0 1 3 5
 
Time Complexity: O(N). Auxiliary Space: O(N).  
sanjeev2552
mohit kumar 29
Kirti_Mangal
patel2127
pankajsharmagfg
divyesh072019
Algorithms
Competitive Programming
Data Structures
Technical Scripter
Tree
Data Structures
Tree
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
DSA Sheet by Love Babbar
Difference between Informed and Uninformed Search in AI
SCAN (Elevator) Disk Scheduling Algorithms
Quadratic Probing in Hashing
K means Clustering - Introduction
Practice for cracking any coding interview
Arrow operator -> in C/C++ with Examples
Competitive Programming - A Complete Guide
Modulo 10^9+7 (1000000007)
Prefix Sum Array - Implementation and Applications in Competitive Programming