Given an undirected tree consisting of N vertices where some of the nodes are special nodes, the task is to visit all the special nodes from the root node in minimum time. Time for traveling from one node to another node can be assumed as unit time.
A node is special if the path from the root to the node consists of distinct value nodes.
Example:Â
Input: N = 7, edges[] = {(0, 1), (0, 2), (1, 4), (1, 5), (2, 3), (2, 6)}Â
isSpecial[] = {false, false, true, false, true, true, false}Â
Output: 8Â
Explanation:Â
Input: N = 7, edges[] = {(0, 1), (0, 2), (1, 4), (1, 5), (2, 3), (2, 6)}Â
isSpecial[] = {false, false, true, false, false, true, false}Â
Output: 6Â
Explanation:Â
Approach: The idea is to use Depth First Search traversal and traverse the nodes. If any node is having a children which is a special node, add two to the steps required for that node. Also mark that node as a special node such that while moving up the steps are taken into consideration.
Below is the implementation of the above approach:Â
C++
// C++ implementation to find // the minimum time required to // visit special nodes of a tree Â
#include <bits/stdc++.h> using namespace std; Â
const int N = 100005; Â
// Time required to collect vector< int > ans(N, 0); Â
vector< int > flag(N, 0); Â
// Minimum time required to reach // all the special nodes of tree void minimumTime( int u, int par, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â vector< bool >& hasApple, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â vector< int > adj[]) { Â
    // Condition to check if     // the vertex has apple     if (hasApple[u] == true )         flag[u] = 1; Â
    // Iterate all the     // adjacent of vertex u.     for ( auto it : adj[u]) { Â
        // if adjacent vertex         // is it's parent         if (it != par) {             minimumTime(it, u, hasApple, adj); Â
            // if any vertex of subtree             // it contain apple             if (flag[it] > 0)                 ans[u] += (ans[it] + 2); Â
            // flagbit for node u             // would be on if any vertex             // in it's subtree contain apple             flag[u] |= flag[it];         }     } } Â
// Driver Code int main() { Â Â Â Â // Number of the vertex. Â Â Â Â int n = 7; Â
    vector< bool > hasApple{ false , false ,                            true , false ,                            true , true ,                            false }; Â
    // Store all the edges,     // any edge represented     // by pair of vertex     vector<pair< int , int > > edges; Â
    // Added all the     // edge in edges vector.     edges.push_back(make_pair(0, 1));     edges.push_back(make_pair(0, 2));     edges.push_back(make_pair(1, 4));     edges.push_back(make_pair(1, 5));     edges.push_back(make_pair(2, 3));     edges.push_back(make_pair(2, 6)); Â
    // Adjacent list     vector< int > adj[n]; Â
    for ( int i = 0; i < edges.size(); i++) {         int source_node = edges[i].first; Â
        int destination_node             = edges[i].second; Â
        adj[source_node]             .push_back(destination_node); Â
        adj[destination_node]             .push_back(source_node);     } Â
    // Function Call     minimumTime(0, -1, hasApple, adj); Â
    cout << ans[0];     return 0; } |
Java
// Java implementation to find // the minimum time required to // visit special nodes of a tree import java.util.*; Â
@SuppressWarnings ( "unchecked" ) public class GFG{ Â
static class pair { Â Â Â Â int first, second; Â Â Â Â Â Â Â Â Â pair( int first, int second) Â Â Â Â { Â Â Â Â Â Â Â Â this .first = first; Â Â Â Â Â Â Â Â this .second = second; Â Â Â Â } } Â
static final int N = 100005 ;   // Time required to collect static ArrayList ans; static ArrayList flag;   // Minimum time required to reach // all the special nodes of tree static void minimumTime( int u, int par,                         ArrayList hasApple,                         ArrayList adj[]) {          // Condition to check if     // the vertex has apple     if (( boolean )hasApple.get(u) == true )         flag.set(u, 1 );       // Iterate all the     // adjacent of vertex u.     for ( int it : (ArrayList<Integer>)adj[u])     {                  // If adjacent vertex         // is it's parent         if (it != par)         {             minimumTime(it, u, hasApple, adj);               // If any vertex of subtree             // it contain apple             if (( int )flag.get(it) > 0 )                 ans.set(u, ( int )ans.get(u) +                            ( int )ans.get(it) + 2 );               // flagbit for node u             // would be on if any vertex             // in it's subtree contain apple             flag.set(u, ( int )flag.get(u) |                         ( int )flag.get(it));         }     } }   // Driver Code public static void main(String []args) {          // Number of the vertex.     int n = 7 ; Â
    ans = new ArrayList();     flag = new ArrayList();          for ( int i = 0 ; i < N; i++)     {         ans.add( 0 );         flag.add( 0 );     }          ArrayList hasApple = new ArrayList();     hasApple.add( false );     hasApple.add( false );     hasApple.add( true );     hasApple.add( false );     hasApple.add( true );     hasApple.add( true );     hasApple.add( false );       // Store all the edges,     // any edge represented     // by pair of vertex     ArrayList edges = new ArrayList();       // Added all the edge in     // edges vector.     edges.add( new pair( 0 , 1 ));     edges.add( new pair( 0 , 2 ));     edges.add( new pair( 1 , 4 ));     edges.add( new pair( 1 , 5 ));     edges.add( new pair( 2 , 3 ));     edges.add( new pair( 2 , 6 ));       // Adjacent list     ArrayList []adj = new ArrayList[n]; Â
    for ( int i = 0 ; i < n; i++)     {         adj[i] = new ArrayList();     }       for ( int i = 0 ; i < edges.size(); i++)     {         int source_node = ((pair)edges.get(i)).first;         int destination_node = ((pair)edges.get(i)).second;           adj[source_node].add(destination_node);         adj[destination_node].add(source_node);     }       // Function Call     minimumTime( 0 , - 1 , hasApple, adj);          System.out.print(ans.get( 0 )); } } Â
// This code is contributed by pratham76 |
Python3
# Python3 implementation to find # the minimum time required to # visit special nodes of a tree N = 100005   # Time required to collect ans = [ 0 for i in range (N)] flag = [ 0 for i in range (N)]   # Minimum time required to reach # all the special nodes of tree def minimumTime(u, par, hasApple, adj):       # Condition to check if     # the vertex has apple     if (hasApple[u] = = True ):         flag[u] = 1       # Iterate all the     # adjacent of vertex u.     for it in adj[u]:           # if adjacent vertex         # is it's parent         if (it ! = par):             minimumTime(it, u, hasApple, adj)               # if any vertex of subtree             # it contain apple             if (flag[it] > 0 ):                 ans[u] + = (ans[it] + 2 )               # flagbit for node u             # would be on if any vertex             # in it's subtree contain apple             flag[u] | = flag[it]   # Driver Code if __name__ = = '__main__' : Â
    # Number of the vertex.     n = 7       hasApple = [ False , False , True ,                  False , True , True , False ]       # Store all the edges,     # any edge represented     # by pair of vertex     edges = []       # Added all the     # edge in edges vector.     edges.append([ 0 , 1 ])     edges.append([ 0 , 2 ])     edges.append([ 1 , 4 ])     edges.append([ 1 , 5 ])     edges.append([ 2 , 3 ])     edges.append([ 2 , 6 ])       # Adjacent list     adj = [[] for i in range (n)]          for i in range ( len (edges)):         source_node = edges[i][ 0 ]                  destination_node = edges[i][ 1 ]           adj[source_node].append(destination_node)         adj[destination_node].append(source_node)          # Function Call     minimumTime( 0 , - 1 , hasApple, adj);          print (ans[ 0 ])      # This code is contributed by rutvik_56 |
C#
// C# implementation to find // the minimum time required to // visit special nodes of a tree using System; using System.Collections.Generic; class GFG {          static int N = 100005;         // Time required to collect     static int [] ans = new int [N];     static int [] flag = new int [N];       // Minimum time required to reach     // all the special nodes of tree     static void minimumTime( int u, int par,                             List< bool > hasApple,                             List<List< int >> adj)     {           // Condition to check if         // the vertex has apple         if (hasApple[u])             flag[u] = 1;           // Iterate all the         // adjacent of vertex u.         for ( int it = 0; it < adj[u].Count; it++)         {               // If adjacent vertex             // is it's parent             if (adj[u][it] != par)             {                 minimumTime(adj[u][it], u, hasApple, adj);                   // If any vertex of subtree                 // it contain apple                 if (flag[adj[u][it]] > 0)                     ans[u] = ans[u] + ans[adj[u][it]] + 2 ;                   // flagbit for node u                 // would be on if any vertex                 // in it's subtree contain apple                 flag[u] = flag[u] | flag[adj[u][it]];             }         }     }        static void Main() {     // Number of the vertex.     int n = 7;            List< bool > hasApple = new List< bool >();     hasApple.Add( false );     hasApple.Add( false );     hasApple.Add( true );     hasApple.Add( false );     hasApple.Add( true );     hasApple.Add( true );     hasApple.Add( false );         // Store all the edges,     // any edge represented     // by pair of vertex     List<Tuple< int , int >> edges = new List<Tuple< int , int >>();         // Added all the edge in     // edges vector.     edges.Add( new Tuple< int , int >(0, 1));     edges.Add( new Tuple< int , int >(0, 2));     edges.Add( new Tuple< int , int >(1, 4));     edges.Add( new Tuple< int , int >(1, 5));     edges.Add( new Tuple< int , int >(2, 3));     edges.Add( new Tuple< int , int >(2, 6));         // Adjacent list     List<List< int >> adj = new List<List< int >>();        for ( int i = 0; i < n; i++)     {         adj.Add( new List< int >());     }         for ( int i = 0; i < edges.Count; i++)     {         int source_node = edges[i].Item1;         int destination_node = edges[i].Item2;             adj[source_node].Add(destination_node);         adj[destination_node].Add(source_node);     }         // Function Call     minimumTime(0, -1, hasApple, adj);            Console.Write(ans[0]);   } } Â
// This code is contributed by divyesh072019. |
Javascript
<script> Â
    // JavaScript implementation to find     // the minimum time required to     // visit special nodes of a tree          let N = 100005;        // Time required to collect     let ans = [];     let flag = []; Â
    // Minimum time required to reach     // all the special nodes of tree     function minimumTime(u, par, hasApple, adj)     { Â
        // Condition to check if         // the vertex has apple         if (hasApple[u] == true )             flag[u] = 1; Â
        // Iterate all the         // adjacent of vertex u.         for (let it = 0; it < adj[u].length; it++)         { Â
            // If adjacent vertex             // is it's parent             if (adj[u][it] != par)             {                 minimumTime(adj[u][it], u, hasApple, adj); Â
                // If any vertex of subtree                 // it contain apple                 if (flag[adj[u][it]] > 0)                     ans[u] = ans[u] + ans[adj[u][it]] + 2 ; Â
                // flagbit for node u                 // would be on if any vertex                 // in it's subtree contain apple                 flag[u] = flag[u] | flag[adj[u][it]];             }         }     }          // Number of the vertex.     let n = 7;       ans = [];     flag = [];           for (let i = 0; i < N; i++)     {         ans.push(0);         flag.push(0);     }           let hasApple = [];     hasApple.push( false );     hasApple.push( false );     hasApple.push( true );     hasApple.push( false );     hasApple.push( true );     hasApple.push( true );     hasApple.push( false );        // Store all the edges,     // any edge represented     // by pair of vertex     let edges = [];        // Added all the edge in     // edges vector.     edges.push([0, 1]);     edges.push([0, 2]);     edges.push([1, 4]);     edges.push([1, 5]);     edges.push([2, 3]);     edges.push([2, 6]);        // Adjacent list     let adj = new Array(n);       for (let i = 0; i < n; i++)     {         adj[i] = [];     }        for (let i = 0; i < edges.length; i++)     {         let source_node = edges[i][0];         let destination_node = edges[i][1];            adj[source_node].push(destination_node);         adj[destination_node].push(source_node);     }        // Function Call     minimumTime(0, -1, hasApple, adj);           document.write(ans[0]);      </script> |
8
Â
Time complexity: O(n)
Auxiliary Space: O(n)
Approach: Using HashMap
 If there’s a special node – travel from the node to the root. So we need a map – child to parent. Do not travel the same path again – mark it as -1 in the map.
Below is the Implementation:
C++
// C++ implementation to find // the minimum time required to // visit special nodes of a tree Â
#include <bits/stdc++.h> using namespace std; Â
int minimumTime( int n, vector<vector< int > >& edges, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â vector< bool >& isSpecial) { Â
    // map to store child to parent     unordered_map< int , int > m; Â
    // sort the edges vector     sort(edges.begin(), edges.end()); Â
    // push into map(child to parent)     for ( auto & edge : edges) {         if (m.count(edge[1]) > 0)             m[edge[0]] = edge[1];         else             m[edge[1]] = edge[0];     } Â
    // create result     int result = 0; Â
    // Traverse over isSpecial vector     for ( int i = 0; i < isSpecial.size(); ++i) {         // if node is not special then continue         if (!isSpecial[i])             continue ; Â
        // take current node as parent         int parent = i; Â
        while (parent != 0 && m[parent] >= 0) {             auto temp = m[parent];             m[parent] = -1;             parent = temp;             result += 2;         }     } Â
    // return result     return result; } Â
int main() { Â
    // Number of the vertex.     int n = 7; Â
    vector< bool > isSpecial{ false , false , true , false ,                             true , true , false }; Â
    // Store all the edges,     // any edge represented     // by pair of vertex     vector<vector< int > > edges         = { { 0, 1 }, { 0, 2 }, { 1, 4 },             { 1, 5 }, { 2, 3 }, { 2, 6 } }; Â
    // Function Call     cout << minimumTime(n, edges, isSpecial); Â
    return 0; } |
Java
// java implementation to find // the minimum time required to // visit special nodes of a tree import java.util.*; public class Main {     static int minimumTime( int n, int [][] edges, boolean [] isSpecial) {       // map to store child to parent         Map<Integer, Integer> m = new HashMap<>();         // sort with respect to child         Arrays.sort(edges, (a, b) -> a[ 0 ] - b[ 0 ]);           // push into map(child to parent)         for ( int [] edge : edges) {             if (m.containsKey(edge[ 1 ])) {                 m.put(edge[ 0 ], edge[ 1 ]);             } else {                 m.put(edge[ 1 ], edge[ 0 ]);             }         } Â
        int result = 0 ;           // Traverse over isSpecial vector         for ( int i = 0 ; i < isSpecial.length; i++) {             // if node is not special then continue             if (!isSpecial[i]) {                 continue ;             }             // taking current node as parent             int parent = i;             while (parent != 0 && m.get(parent) >= 0 ) {                 int temp = m.get(parent);                 m.put(parent, - 1 );                 parent = temp;                 result += 2 ;             }         }         // return the result         return result;     } Â
    public static void main(String[] args) {           // Number of vertex         int n = 7 ;         // Store all the edges,            // any edge represented            // by pair of vertex         boolean [] isSpecial = { false , false , true , false , true , true , false };         int [][] edges = {{ 0 , 1 }, { 0 , 2 }, { 1 , 4 }, { 1 , 5 }, { 2 , 3 }, { 2 , 6 }};         // Function call         System.out.println(minimumTime(n, edges, isSpecial));     } } |
Python3
from collections import defaultdict Â
def minimumTime(n, edges, isSpecial):        # Create a dictionary to store the parent-child relationship     m = defaultdict( int ) Â
    # Sort the edges list     edges.sort() Â
    # Add the parent-child relationship to the dictionary     for edge in edges:         if edge[ 1 ] in m:             m[edge[ 0 ]] = edge[ 1 ]         else :             m[edge[ 1 ]] = edge[ 0 ] Â
    # Initialize the result     result = 0 Â
    # Traverse over the isSpecial list     for i in range ( len (isSpecial)):         # If the node is not special, continue         if not isSpecial[i]:             continue Â
        # Take the current node as the parent         parent = i Â
        # Traverse through the parent-child relationship         while parent ! = 0 and m[parent] > = 0 :             temp = m[parent]             m[parent] = - 1             parent = temp             result + = 2 Â
    # Return the result     return result Â
# Number of vertices n = 7 Â
# List of special nodes isSpecial = [ False , False , True , False , True , True , False ] Â
# List of edges edges = [[ 0 , 1 ], [ 0 , 2 ], [ 1 , 4 ], [ 1 , 5 ], [ 2 , 3 ], [ 2 , 6 ]] Â
# Call the function print (minimumTime(n, edges, isSpecial)) |
C#
using System; using System.Collections.Generic; using System.Linq; Â
class Program { Â
  static int MinimumTime( int n, List<List< int >> edges, List< bool > isSpecial) { Â
    // Dictionary to store child to parent     Dictionary< int , int > m = new Dictionary< int , int >(); Â
    // Sort the edges list     edges.Sort((a, b) => a[0].CompareTo(b[0])); Â
    // Push into dictionary (child to parent)     foreach ( var edge in edges) {       if (m.ContainsKey(edge[1]))         m[edge[0]] = edge[1];       else         m[edge[1]] = edge[0];     } Â
    // Create result     int result = 0; Â
    // Traverse over isSpecial list     for ( int i = 0; i < isSpecial.Count; i++) {       // If node is not special then continue       if (!isSpecial[i])         continue ; Â
      // Take current node as parent       int parent = i; Â
      while (parent != 0 && m[parent] >= 0) {         int temp = m[parent];         m[parent] = -1;         parent = temp;         result += 2;       }     } Â
    // Return result     return result;   } Â
  static void Main() { Â
    // Number of vertices     int n = 7; Â
    List< bool > isSpecial = new List< bool > { false , false , true , false , true , true , false }; Â
    // Store all the edges,     // any edge represented by a pair of vertices     List<List< int >> edges = new List<List< int >> {       new List< int > { 0, 1 },       new List< int > { 0, 2 },       new List< int > { 1, 4 },       new List< int > { 1, 5 },       new List< int > { 2, 3 },       new List< int > { 2, 6 }     }; Â
    // Function call     Console.WriteLine(MinimumTime(n, edges, isSpecial));   } } |
Javascript
// JavaScript implementation to find the minimum time // required to visit special nodes of a tree Â
const minimumTime = (n, edges, isSpecial) => {   // map to store child to parent   const m = new Map(); Â
  // sort the edges array   edges.sort((a, b) => a[0] - b[0]); Â
  // push into map(child to parent)   edges.forEach(edge => {     if (m.has(edge[1])) m.set(edge[0], edge[1]);     else m.set(edge[1], edge[0]);   }); Â
  // create result   let result = 0; Â
  // Traverse over isSpecial array   for (let i = 0; i < isSpecial.length; i++) {     // if node is not special then continue     if (!isSpecial[i]) continue ; Â
    // take current node as parent     let parent = i; Â
    while (parent != 0 && m.get(parent) >= 0) {       const temp = m.get(parent);       m.set(parent, -1);       parent = temp;       result += 2;     }   } Â
  // return result   return result; }; Â
// Number of the vertex. const n = 7; Â
const isSpecial = [ false , false , true , false , true , true , false ]; Â
// Store all the edges, any edge represented by pair of vertex const edges = [[0, 1], [0, 2], [1, 4], [1, 5], [2, 3], [2, 6]]; Â
// Function Call console.log(minimumTime(n, edges, isSpecial)); |
8
Time complexity: O(n Log n)
Auxiliary Space: O(n)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!