Minimum time required to visit all the special nodes of a Tree

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 defaultdictdef 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 treeconst 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 zambiatek!




