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 collectvector<int> ans(N, 0);Â
vector<int> flag(N, 0);Â
// Minimum time required to reach// all the special nodes of treevoid 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 Codeint 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 treeimport 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 collectstatic ArrayList ans;static ArrayList flag;  // Minimum time required to reach// all the special nodes of treestatic 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 Codepublic 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 treeN = 100005  # Time required to collectans = [0 for i in range(N)]flag = [0 for i in range(N)]  # Minimum time required to reach# all the special nodes of treedef 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 Codeif __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 treeusing 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 treeimport 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 verticesn = 7Â
# List of special nodesisSpecial = [False, False, True, False, True, True, False]Â
# List of edgesedges = [[0, 1], [0, 2], [1, 4], [1, 5], [2, 3], [2, 6]]Â
# Call the functionprint(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 vertexconst edges = [[0, 1], [0, 2], [1, 4], [1, 5], [2, 3], [2, 6]];Â
// Function Callconsole.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!

