Kth ancestor of all nodes in an N-ary tree using DFS

Given an N-ary tree and an integer K, the task is to print the Kth ancestors of all the nodes of the tree in level order manner. If K ancestors does not exist for a node, then print -1 for that node.

Examples:

Input: K = 2


Output: -1 -1 -1 1 1 1 1 1 1
Explanation:
2nd ancestor does not exist for nodes 1, 2 and 3
2nd ancestor of nodes 4, 5, 6, 7, 8, 9 is 1.

Input: K = 1


Output: -1 1 1 2 2 2 3 3 3

Approach: The approach is to use DFS to find the ancestors of all the nodes. Below are the steps:



  1. The Kthparent of any node can be found by using DFS, and storing all parents of a node in a temporary vector say temp[].
  2. Whenever a node is visited in DFS, it is pushed in the temp vector.
  3. At the end of DFS, the currently visited node is popped from the temp vector.
  4. For the currently visited node, the vector contains all the ancestors of the node.
  5. The Kth node from the end of the vector is the Kth ancestor of the currently visited node, so store it in a ancestor[] array.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of
// the above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to add an
// edge in the tree
void addEdge(vector<int> v[],
             int x, int y)
{
    v[x].push_back(y);
    v[y].push_back(x);
}
  
// DFS to find the Kth
// ancestor of every node
void dfs(vector<int> tree[],
         vector<int>& temp,
         int ancestor[], int u,
         int parent, int k)
{
    // Pushing current node
    // in the vector
    temp.push_back(u);
  
    // Traverse its neighbors
    for (auto i : tree[u]) {
        if (i == parent)
            continue;
        dfs(tree, temp,
            ancestor, i, u, k);
    }
  
    temp.pop_back();
  
    // If K ancestors are not
    // found for current node
    if (temp.size() < k) {
        ancestor[u] = -1;
    }
    else {
  
        // Add the Kth ancestor
        // for the node
        ancestor[u]
            = temp[temp.size() - k];
    }
}
  
// Function to find Kth
// ancestor of each node
void KthAncestor(int N, int K, int E,
                 int edges[][2])
{
  
    // Building the tree
    vector<int> tree[N + 1];
    for (int i = 0; i < E; i++) {
        addEdge(tree, edges[i][0],
                edges[i][1]);
    }
  
    // Stores all parents of a node
    vector<int> temp;
  
    // Store Kth ancestor
    // of all nodes
    int ancestor[N + 1];
  
    dfs(tree, temp, ancestor, 1, 0, K);
  
    // Print the ancestors
    for (int i = 1; i <= N; i++) {
        cout << ancestor[i] << " ";
    }
}
  
int main()
{
    // Given N and K
    int N = 9;
    int K = 2;
  
    // Given edges of n-ary tree
    int E = 8;
    int edges[8][2] = { { 1, 2 }, { 1, 3 }, { 2, 4 }, 
                        { 2, 5 }, { 2, 6 }, { 3, 7 }, 
                        { 3, 8 }, { 3, 9 } };
  
    // Function Call
    KthAncestor(N, K, E, edges);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of
// the above approach
import java.util.*;
  
class GFG{
  
// Function to add an
// edge in the tree
static void addEdge(Vector<Integer> v[],
                    int x, int y)
{
    v[x].add(y);
    v[y].add(x);
}
  
// DFS to find the Kth
// ancestor of every node
static void dfs(Vector<Integer> tree[],
                Vector<Integer> temp,
                int ancestor[], int u,
                int parent, int k)
{
      
    // Pushing current node
    // in the vector
    temp.add(u);
  
    // Traverse its neighbors
    for(int i : tree[u])
    {
        if (i == parent)
            continue;
              
        dfs(tree, temp,
            ancestor, i, u, k);
    }
  
    temp.remove(temp.size() - 1);
  
    // If K ancestors are not
    // found for current node
    if (temp.size() < k) 
    {
        ancestor[u] = -1;
    }
    else 
    {
  
        // Add the Kth ancestor
        // for the node
        ancestor[u] = temp.get(temp.size() - k);
    }
}
  
// Function to find Kth
// ancestor of each node
static void KthAncestor(int N, int K, int E,
                        int edges[][])
{
  
    // Building the tree
    @SuppressWarnings("unchecked")
    Vector<Integer> []tree = new Vector[N + 1];
    for(int i = 0; i < tree.length; i++)
        tree[i] = new Vector<Integer>();
          
    for(int i = 0; i < E; i++)
    {
        addEdge(tree, edges[i][0],
                      edges[i][1]);
    }
  
    // Stores all parents of a node
    Vector<Integer> temp = new Vector<Integer>();
  
    // Store Kth ancestor
    // of all nodes
    int []ancestor = new int[N + 1];
  
    dfs(tree, temp, ancestor, 1, 0, K);
  
    // Print the ancestors
    for(int i = 1; i <= N; i++)
    {
        System.out.print(ancestor[i] + " ");
    }
}
  
// Driver code
public static void main(String[] args)
{
      
    // Given N and K
    int N = 9;
    int K = 2;
  
    // Given edges of n-ary tree
    int E = 8;
    int edges[][] = { { 1, 2 }, { 1, 3 },
                      { 2, 4 }, { 2, 5 },
                      { 2, 6 }, { 3, 7 }, 
                      { 3, 8 }, { 3, 9 } };
  
    // Function call
    KthAncestor(N, K, E, edges);
}
}
  
// This code is contributed by Amit Katiyar
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of
# the above approach
  
# Function to add an
# edge in the tree
def addEdge(v, x, y):
  
    v[x].append(y)
    v[y].append(x)
  
# DFS to find the Kth
# ancestor of every node
def dfs(tree, temp, ancestor, u, parent, k):
  
    # Pushing current node
    # in the vector
    temp.append(u)
  
    # Traverse its neighbors
    for i in tree[u]:
        if (i == parent):
            continue
              
        dfs(tree, temp, ancestor, i, u, k)
  
    temp.pop()
  
    # If K ancestors are not
    # found for current node
    if (len(temp) < k):
        ancestor[u] = -1
  
    else:
  
        # Add the Kth ancestor
        # for the node
        ancestor[u] = temp[len(temp) - k]
  
# Function to find Kth
# ancestor of each node
def KthAncestor(N, K, E, edges):
  
    # Building the tree
    tree = [[] for i in range(N + 1)]
    for i in range(E):
        addEdge(tree, edges[i][0], 
                      edges[i][1])
  
    # Stores all parents of a node
    temp = []
  
    # Store Kth ancestor
    # of all nodes
    ancestor = [0] * (N + 1)
  
    dfs(tree, temp, ancestor, 1, 0, K)
  
    # Print the ancestors
    for i in range(1, N + 1):
        print(ancestor[i], end = " ")
  
# Driver code
if __name__ == '__main__':
      
    # Given N and K
    N = 9
    K = 2
  
    # Given edges of n-ary tree
    E = 8
    edges = [ [ 1, 2 ], [ 1, 3 ], 
              [ 2, 4 ], [ 2, 5 ], 
              [ 2, 6 ], [ 3, 7 ],
              [ 3, 8 ], [ 3, 9 ] ]
  
    # Function call
    KthAncestor(N, K, E, edges)
  
# This code is contributed by mohit kumar 29
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of
// the above approach
using System;
using System.Collections.Generic;
  
class GFG{
  
// Function to add an
// edge in the tree
static void addEdge(List<int> []v,
                    int x, int y)
{
    v[x].Add(y);
    v[y].Add(x);
}
  
// DFS to find the Kth
// ancestor of every node
static void dfs(List<int> []tree,
                List<int> temp,
                int []ancestor, int u,
                int parent, int k)
{
      
    // Pushing current node
    // in the vector
    temp.Add(u);
  
    // Traverse its neighbors
    foreach(int i in tree[u])
    {
        if (i == parent)
            continue;
              
        dfs(tree, temp,
            ancestor, i, u, k);
    }
  
    temp.RemoveAt(temp.Count - 1);
  
    // If K ancestors are not
    // found for current node
    if (temp.Count < k) 
    {
        ancestor[u] = -1;
    }
    else
    {
  
        // Add the Kth ancestor
        // for the node
        ancestor[u] = temp[temp.Count - k];
    }
}
  
// Function to find Kth
// ancestor of each node
static void KthAncestor(int N, int K, int E,
                        int [,]edges)
{
  
    // Building the tree
    List<int> []tree = new List<int>[N + 1];
    for(int i = 0; i < tree.Length; i++)
        tree[i] = new List<int>();
          
    for(int i = 0; i < E; i++)
    {
        addEdge(tree, edges[i, 0],
                      edges[i, 1]);
    }
  
    // Stores all parents of a node
    List<int> temp = new List<int>();
  
    // Store Kth ancestor
    // of all nodes
    int []ancestor = new int[N + 1];
  
    dfs(tree, temp, ancestor, 1, 0, K);
  
    // Print the ancestors
    for(int i = 1; i <= N; i++)
    {
        Console.Write(ancestor[i] + " ");
    }
}
  
// Driver code
public static void Main(String[] args)
{
      
    // Given N and K
    int N = 9;
    int K = 2;
  
    // Given edges of n-ary tree
    int E = 8;
    int [,]edges = { { 1, 2 }, { 1, 3 },
                     { 2, 4 }, { 2, 5 },
                     { 2, 6 }, { 3, 7 }, 
                     { 3, 8 }, { 3, 9 } };
  
    // Function call
    KthAncestor(N, K, E, edges);
}
}
  
// This code is contributed by Amit Katiyar
chevron_right

Output:
-1 -1 -1 1 1 1 1 1 1


Time complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :