Minimum time to visit all nodes of given Graph at least once
Last Updated : 16 Sep, 2024
Given a graph and the list of neighbours for each nodein an array graph[] of size N, where graph[i] contains a list of neighbor nodes that are connected to ithnode, the task is to visit all the nodes of the given graph in a minimum amount of time.
Note: Movement from any node to its neighbour takes one unit of time
Example:
Input: [[1, 2, 3], [2, 0], [0, 1], [0, 4], [3]] Output: 4 Explanation: One possible way to visit all node in minimum number of time is shown by the below graph
Input: [[1, 2, 3], [2, 0], [0, 1], [0]] Output: 3
An approach using BFS + BitMasking:
Usually it is best to use BFS to find the minimum time problem in graph. However, in this case, we cannot use traditional BFS since traditional BFS can only visit the elements once. In this case, repetition is allowed, which means we can traverse any node multiple times, leading to an infinite loop. To handle infinite loop we can use Bitmasking to store the states while moving over graph.
Follow the step below to implement the above idea:
Create an adjacency list from the given graph
Initialize a variable finalMask = (1 << number_of_nodes) - 1, this represent the state when all node has been visited.
Initialize a variable timeCount = 0 to keep track of the minimum time to visit all nodes.
Initialize a queue for BFS which will store the current node id and mask of visited nodes.
Initialize a 2D array visited[][] for keeping track of nodes with all possible masks that are visited in the path.
Push every node as a starting node for all possible paths with their mask for counting the number of the minimum time to visit all the node
While the queue is not empty:
Iterate over each level
Fetch and pop the current node
Check if the current node mask is equal to finalMask:
If the condition is true, return timeCount as the result.
Explore all the children of the current node:
Make a new mask for the child by toggling the ith bit of the current Mask.
If the new mask for the child has not been visited yet, push the child and new Mask in the queue and mark visited for the child with new mask.
Increment the time Count after each level
Below is the implementation of the above approach:
C++
// C++ code to implement the approach#include<bits/stdc++.h>usingnamespacestd;// Function to calculate the minimum timeintminimizeTime(vector<vector<int>>&graph){longlongn=graph.size();// Create adjacency list from the given graphvector<vector<longlong>>adj(n);for(inti=0;i<n;i++){for(autoj:graph[i]){adj[i].push_back(j);}}// Final mask when all the node will be visitedlonglongfinalMask=(longlong)(1<<n)-1;// Initialize a queue for BFS which will store current// node id and mask of visited nodes.queue<pair<longlong,longlong>>q;// Initialize a visited array for keeping track// of all mask that are visited in the pathvector<vector<bool>>visited(n,vector<bool>(finalMask+1));// Push starting node for// all possible path with their maskfor(inti=0;i<n;i++){q.push({i,(longlong)(1<<i)});}// For counting the minimum time// to visit all the nodeslonglongtimeCount=0;// Do while q.size > 0while(q.size()>0){intsize=q.size();// Iterate over each levelfor(inti=0;i<size;i++){// Fetch and pop the current nodeautocurr=q.front();q.pop();// Check if the current node mask// is equal to finalMaskif(curr.second==finalMask)returntimeCount;// Explore all the child of current nodefor(autochild:adj[curr.first]){// Make a new Mask for childlonglongnewVisitedBit=curr.second|(1<<child);// If new Mask for child has// not been visited yet,// push child and new Mask in// the queue and mark visited// for child with newVisitedBitif(visited[child][newVisitedBit]==false){q.push({child,newVisitedBit});visited[child][newVisitedBit]=true;}}}// Increment the time Count after each leveltimeCount++;}// If all node can't be visitedreturn-1;}// Driver codeintmain(){vector<vector<int>>graph={{1,2,3},{2,0},{0,1},{0,4},{3}};// Function callintminTime=minimizeTime(graph);cout<<minTime<<endl;return0;}
Java
// Java code to implement the approachimportjava.util.*;// Pair classclassPair{intfirst,second;Pair(intfirst,intsecond){this.first=first;this.second=second;}publicintgetKey(){returnthis.first;}publicintgetValue(){returnthis.second;}}classGFG{// Function to calculate the minimum timepublicstaticintminimizeTime(ArrayList<ArrayList<Integer>>graph){intn=graph.size();// Create adjacency list from the given graphArrayList<ArrayList<Integer>>adj=newArrayList<ArrayList<Integer>>(n);for(inti=0;i<n;i++){adj.add(newArrayList<Integer>());for(intj:graph.get(i)){adj.get(i).add(j);}}// Final mask when all the node will be visitedintfinalMask=(1<<n)-1;// Initialize a queue for BFS which will store// current node id and mask of visited nodes.Queue<Pair>q=newLinkedList<Pair>();// Initialize a visited array for keeping track// of all mask that are visited in the pathboolean[][]visited=newboolean[n][finalMask+1];// Push starting node for// all possible path with their maskfor(inti=0;i<n;i++){q.add(newPair(i,(1<<i)));}// For counting the minimum time// to visit all the nodesinttimeCount=0;// Do while q.size > 0while(q.size()>0){intsize=q.size();// Iterate over each levelfor(inti=0;i<size;i++){// Fetch and pop the current nodePaircurr=q.poll();// Check if the current node mask// is equal to finalMaskif(curr.getValue()==finalMask)returntimeCount;// Explore all the child of current nodefor(intchild:adj.get(curr.getKey())){// Make a new Mask for childintnewVisitedBit=curr.getValue()|(1<<child);// If new Mask for child has// not been visited yet,// push child and new Mask in// the queue and mark visited// for child with newVisitedBitif(visited[child][newVisitedBit]==false){q.add(newPair(child,newVisitedBit));visited[child][newVisitedBit]=true;}}}// Increment the time Count after each leveltimeCount++;}// If all node can't be visitedreturn-1;}// Driver codepublicstaticvoidmain(String[]args){ArrayList<ArrayList<Integer>>graph=newArrayList<ArrayList<Integer>>();graph.add(newArrayList<Integer>(Arrays.asList(1,2,3)));graph.add(newArrayList<Integer>(Arrays.asList(2,0)));graph.add(newArrayList<Integer>(Arrays.asList(0,1)));graph.add(newArrayList<Integer>(Arrays.asList(0,4)));graph.add(newArrayList<Integer>(Arrays.asList(3)));// Function callintminTime=minimizeTime(graph);System.out.println(minTime);}}// This code is contributed by Tapesh(tapeshdua420)
Python
# Python code to implement the approach# Function to calculate the minimum timedefminimizeTime(graph):n=len(graph)# Create adjacency list from the given graphadj=[[]foriinrange(n)]foriinrange(n):forjingraph[i]:adj[i].append(j)# Final mask when all the node will be visitedfinalMask=(1<<n)-1# Initialize a queue for BFS which will store current# node id and mask of visited nodes.q=[]# Initialize a visited array for keeping track# of all mask that are visited in the pathvisited=[[0foriinrange(finalMask+1)]forjinrange(n)]# Push starting node for# all possible path with their maskforiinrange(n):q.append([i,1<<i])# For counting the minimum time# to visit all the nodestimeCount=0# Do while q.size > 0while(len(q)>0):size=len(q)# Iterate over each levelforiinrange(size):# Fetch and pop the current nodecurr=q.pop(0)# Check if the current node mask# is equal to finalMaskif(curr[1]==finalMask):returntimeCount# Explore all the child of current nodeforchildinadj[curr[0]]:# Make a new Mask for childnewVisitedBit=curr[1]|(1<<child)# If new Mask for child has# not been visited yet,# push child and new Mask in# the queue and mark visited# for child with newVisitedBitif(visited[child][newVisitedBit]==False):q.append([child,newVisitedBit])visited[child][newVisitedBit]=True# Increment the time Count after each leveltimeCount=timeCount+1# If all node can't be visitedreturn-1# Driver codegraph=[[1,2,3],[2,0],[0,1],[0,4],[3]]# Function callaminTime=minimizeTime(graph)print(minTime)# This code is contributed by Pushpesh Raj.
C#
// C# code to implement the approachusingSystem;usingSystem.Collections.Generic;classProgram{// Driver codestaticvoidMain(string[]args){List<List<int>>graph=newList<List<int>>();graph.Add(newList<int>(newint[]{1,2,3}));graph.Add(newList<int>(newint[]{2,0}));graph.Add(newList<int>(newint[]{0,1}));graph.Add(newList<int>(newint[]{0,4}));graph.Add(newList<int>(newint[]{3}));// Function callintminTime=minimizeTime(graph);Console.WriteLine(minTime);}// Function to calculate the minimum timepublicstaticintminimizeTime(List<List<int>>graph){intn=graph.Count;// Create adjacency list from the given graphList<List<int>>adj=newList<List<int>>(n);for(inti=0;i<n;i++){adj.Add(newList<int>());foreach(intjingraph[i]){adj[i].Add(j);}}// Final mask when all the node will be visitedintfinalMask=(1<<n)-1;// Initialize a queue for BFS which will store// current node id and mask of visited nodes.Queue<Pair>q=newQueue<Pair>();// Initialize a visited array for keeping track// of all mask that are visited in the pathbool[,]visited=newbool[n,finalMask+1];// Push starting node for// all possible path with their maskfor(inti=0;i<n;i++){q.Enqueue(newPair(i,(1<<i)));}// For counting the minimum time// to visit all the nodesinttimeCount=0;// Do while q.size > 0while(q.Count>0){intsize=q.Count;// Iterate over each levelfor(inti=0;i<size;i++){// Fetch and pop the current nodePaircurr=q.Dequeue();// Check if the current node mask// is equal to finalMaskif(curr.getValue()==finalMask)returntimeCount;// Explore all the child of current nodeforeach(intchildinadj[curr.getKey()]){// Make a new Mask for childintnewVisitedBit=curr.getValue()|(1<<child);// If new Mask for child has// not been visited yet,// push child and new Mask in// the queue and mark visited// for child with newVisitedBitif(visited[child,newVisitedBit]==false){q.Enqueue(newPair(child,newVisitedBit));visited[child,newVisitedBit]=true;}}}// Increment the time Count after each leveltimeCount++;}// If all node can't be visitedreturn-1;}}// Pair classclassPair{publicintfirst,second;publicPair(intfirst,intsecond){this.first=first;this.second=second;}publicintgetKey(){returnthis.first;}publicintgetValue(){returnthis.second;}}// This code is contributed by Tapesh(tapeshdua420)
JavaScript
// JavaScript code to implement the approach// Function to calculate the minimum timefunctionminimizeTime(graph){varn=graph.length;// Create adjacency list from the given graphvaradj=[];for(vari=0;i<n;i++){adj.push([]);for(varj=0;j<graph[i].length;j++){adj[i].push(graph[i][j]);}}// Final mask when all the node will be visitedvarfinalMask=(1<<n)-1;// Initialize a queue for BFS which will store current// node id and mask of visited nodes.varq=[];// Initialize a visited array for keeping track// of all mask that are visited in the pathvarvisited=[];for(vari=0;i<n;i++){visited.push([]);for(varj=0;j<=finalMask;j++){visited[i].push(0);}}// Push starting node for// all possible path with their maskfor(vari=0;i<n;i++){q.push([i,1<<i]);}// For counting the minimum time// to visit all the nodesvartimeCount=0;// Do while q.size > 0while(q.length>0){varsize=q.length;// Iterate over each levelfor(vari=0;i<size;i++){// Fetch and pop the current nodevarcurr=q.shift();// Check if the current node mask// is equal to finalMaskif(curr[1]==finalMask){returntimeCount;}// Explore all the child of current nodefor(varj=0;j<adj[curr[0]].length;j++){varchild=adj[curr[0]][j];// Make a new Mask for childvarnewVisitedBit=curr[1]|(1<<child);// If new Mask for child has// not been visited yet,// push child and new Mask in// the queue and mark visited// for child with newVisitedBitif(visited[child][newVisitedBit]==false){q.push([child,newVisitedBit]);visited[child][newVisitedBit]=true;}}}// Increment the time Count after each leveltimeCount=timeCount+1;}// If all node can't be visitedreturn-1;}// Driver codevargraph=[[1,2,3],[2,0],[0,1],[0,4],[3]];// Function callvarminTime=minimizeTime(graph);console.log(minTime);// This code is contributed by Tapesh(tapeshdua420).
Output
4
Time Complexity: O(V*2^V) where V is the number of vertices and E is the number of edges. Auxiliary Space: O(V*2^V)