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++ 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 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 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# 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. |
<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++ 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 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));
}
} |
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))
|
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 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)