Given an undirected connected graph of N nodes and M edges. Each node has a light but at a time it can be either green or red. Initially, all the node is of green color. After every T seconds, the color of light changes from green to red and vice-versa. It is possible to travel from node U to node V only if the color of node U is green. The time taken required to travel through any edges is C seconds. Find the minimum amount of time required to travel from node 1 to node N.
Examples:
Input: N = 5, M = 5, T = 3, C = 5
Edges[] = {{1, 2}, {1, 3}, {1, 4}, {2, 4}, {2, 5}}
Output: 11
Explanation: At 0sec, the color of node 1 is green, so travel from node 1 to node 2 in 5sec.
Now at 5sec, the color of node 2 is red so wait 1sec to change into green.
Now at 6sec, the color of node 2 is green, so travel from node 2 to node 5 in 5sec.
Total time = 5(from node 1 to node 2) + 1(wait at node 2) + 5(from node 2 to node 5) = 11 sec.
Approach: The given problem can be solved by using Breadth-First Search and Dijkstra Algorithm because the problem is similar to the shortest path problem. Follow the steps below to solve the problem:
- Initialize a queue, say Q that stores the nodes that are to be traversed and the time required to reach that node.
- Create a boolean array, say V that stores whether the present node is visited or not.
- Push node 1 and time 0 as a pair in the queue Q.
- Consider that there is always green light and traveling through edges requires 1 second then simply run the BFS and find the shortest time required to reach from node 1 to node N and store it in a variable, say time.
- Create a function findTime which finds the time if traveling through edges requires C seconds and the light color changes after T seconds by performing the following steps:
- Initialize a variable ans as 0 that will store the minimum time required to reach from node 1 to node N.
- Iterate in the range [0, time] using the variable i and perform the following steps:
- If (ans/T) %2 = 1, then modify the value of ans as (ans/T + 1)* T + C.
- Otherwise, add C to the variable ans.
- Print ans as the answer.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find min edge int minEdge(vector<vector< int > > X, int N, int M, int T, int C) { // Initialize queue and push [1, 0] queue<pair< int , int > > Q; Q.push({1, 0}); // Create visited array to keep the // track if node is visited or not vector< int > V(N+1, false ); // Run infinite loop int crnt, c; while (1) { crnt = Q.front().first; c = Q.front().second; Q.pop(); // If node is N, terminate loop if (crnt == N) break ; // Travel adjacent nodes of crnt for ( int _ : X[crnt]) { // Check whether we visited previously or not if (!V[_]) { // Push into queue and make as true Q.push({_, c + 1}); V[_] = true ; } } } return c; } // Function to Find time required to reach 1 to N int findTime( int T, int C, int c) { int ans = 0; for ( int _ = 0; _ < c; _++) { // Check color of node is red or green if ((ans/T) % 2) // Add C sec from next green color time ans = (ans/T + 1)*T + C; else // Add C ans += C; } // Return the answer return ans; } // Driver Code int main() { // Given Input int N = 5; int M = 5; int T = 3; int C = 5; vector<vector< int > > X{{}, {2, 3, 4}, {4, 5}, {1}, {1, 2}, {2}}; // Function Call int c = minEdge(X, N, M, T, C); int ans = findTime(T, C, c); // Print total time cout << (ans) << endl; return 0; } // This code is contributed by Dharanendra L V. |
Java
import java.util.AbstractMap.SimpleEntry; import java.util.ArrayDeque; import java.util.Queue; import java.util.Vector; public class MinEdge { // Function to find min edge public static int minEdge(Vector<Vector<Integer> > X, int N, int M, int T, int C) { // Initialize queue and push [1, 0] Queue<SimpleEntry<Integer, Integer> > Q = new ArrayDeque< SimpleEntry<Integer, Integer> >(); Q.add( new SimpleEntry<Integer, Integer>( 1 , 0 )); // Create visited array to keep the // track if node is visited or not Vector<Boolean> V = new Vector<Boolean>(N + 1 ); for ( int i = 0 ; i <= N; i++) { V.add( false ); } // Run infinite loop int crnt, c; while ( true ) { crnt = Q.peek().getKey(); c = Q.peek().getValue(); Q.remove(); // If node is N, terminate loop if (crnt == N) break ; // Travel adjacent nodes of crnt for ( int i : X.get(crnt)) { // Check whether we visited previously or // not if (!V.get(i)) { // Push into queue and make as true Q.add( new SimpleEntry<Integer, Integer>( i, c + 1 )); V.set(i, true ); } } } return c; } // Function to Find time required to reach 1 to N public static int findTime( int T, int C, int c) { int ans = 0 ; for ( int i = 0 ; i < c; i++) { // Check color of node is red or green if ((ans / T) % 2 == 1 ) // Add C sec from next green color time ans = (ans / T + 1 ) * T + C; else // Add C ans += C; } // Return the answer return ans; } // Driver Code public static void main(String[] args) { // Given Input int N = 5 ; int M = 5 ; int T = 3 ; int C = 5 ; Vector<Vector<Integer> > X = new Vector<Vector<Integer> >(); for ( int i = 0 ; i <= N; i++) { X.add( new Vector<Integer>()); } X.get( 1 ).add( 2 ); X.get( 1 ).add( 3 ); X.get( 1 ).add( 4 ); X.get( 2 ).add( 4 ); X.get( 2 ).add( 5 ); X.get( 3 ).add( 1 ); X.get( 4 ).add( 1 ); X.get( 4 ).add( 2 ); X.get( 5 ).add( 2 ); int c = minEdge(X, N, M, T, C); int ans = findTime(T, C, c); System.out.println(ans); } } // This code is contributed by aadityamaharshi21. |
Python3
# Python program for the above approach # Import library for Queue from queue import Queue # Function to find min edge def minEdge(): # Initialize queue and push [1, 0] Q = Queue() Q.put([ 1 , 0 ]) # Create visited array to keep the # track if node is visited or not V = [ False for _ in range (N + 1 )] # Run infinite loop while 1 : crnt, c = Q.get() # If node is N, terminate loop if crnt = = N: break # Travel adjacent nodes of crnt for _ in X[crnt]: # Check whether we visited previously or not if not V[_]: # Push into queue and make as true Q.put([_, c + 1 ]) V[_] = True return c # Function to Find time required to reach 1 to N def findTime(c): ans = 0 for _ in range (c): # Check color of node is red or green if (ans / / T) % 2 : # Add C sec from next green color time ans = (ans / / T + 1 ) * T + C else : # Add C ans + = C # Return the answer return ans # Driver Code if __name__ = = "__main__" : # Given Input N = 5 M = 5 T = 3 C = 5 X = [[], [ 2 , 3 , 4 ], [ 4 , 5 ], [ 1 ], [ 1 , 2 ], [ 2 ]] # Function Call c = minEdge() ans = findTime(c) # Print total time print (ans) |
C#
using System; using System.Collections.Generic; class Program { // Function to find min edge static int MinEdge(List< int >[] X, int N, int M, int T, int C) { // Initialize queue and push [1, 0] Queue< int []> Q = new Queue< int []>(); Q.Enqueue( new int [] { 1, 0 }); // Create visited array to keep the // track if node is visited or not bool [] V = new bool [N + 1]; // Run infinite loop int crnt, c; while ( true ) { int [] arr = Q.Dequeue(); crnt = arr[0]; c = arr[1]; // If node is N, terminate loop if (crnt == N) break ; // Travel adjacent nodes of crnt foreach ( int i in X[crnt]) { // Check whether we visited previously or not if (!V[i]) { // Push into queue and make as true Q.Enqueue( new int [] { i, c + 1 }); V[i] = true ; } } } return c; } // Function to Find time required to reach 1 to N static int FindTime( int T, int C, int c) { int ans = 0; for ( int i = 0; i < c; i++) { // Check color of node is red or green if ((ans / T) % 2 == 1) { // Add C sec from next green color time ans = (ans / T + 1) * T + C; } else { // Add C ans += C; } } // Return the answer return ans; } static void Main( string [] args) { // Given Input int N = 5; int M = 5; int T = 3; int C = 5; List< int >[] X = new List< int >[N + 1]; for ( int i = 0; i <= N; i++) { X[i] = new List< int >(); } X[1].AddRange( new int [] { 2, 3, 4 }); X[2].AddRange( new int [] { 4, 5 }); X[3].Add(1); X[4].AddRange( new int [] { 1, 2 }); X[5].Add(2); // Function Call int c = MinEdge(X, N, M, T, C); int ans = FindTime(T, C, c); // Print total time Console.WriteLine(ans); } } |
Javascript
// Function to find min edge function minEdge(X, N, M, T, C) { // Initialize queue and push [1, 0] let Q = []; Q.push([1, 0]); // Create visited array to keep the // track if node is visited or not let V = Array(N+1).fill( false ); // Run infinite loop let crnt, c; while ( true ) { [crnt, c] = Q.shift(); // If node is N, terminate loop if (crnt === N) break ; // Travel adjacent nodes of crnt for (let _ of X[crnt]) { // Check whether we visited previously or not if (!V[_]) { // Push into queue and make as true Q.push([_, c + 1]); V[_] = true ; } } } return c; } // Function to Find time required to reach 1 to N function findTime(T, C, c) { let ans = 0; for (let _ = 0; _ < c; _++) { // Check color of node is red or green if ((ans/T) % 2) // Add C sec from next green color time ans = (ans/T + 1)*T + C; else // Add C ans += C; } // Return the answer return ans; } // Driver Code function main() { // Given Input let N = 5; let M = 5; let T = 3; let C = 5; let X = [[], [2, 3, 4], [4, 5], [1], [1, 2], [2]]; // Function Call let c = minEdge(X, N, M, T, C); let ans = findTime(T, C, c); // Print total time console.log(ans); return 0; } main(); // This code is contributed by aadityamaharshi21. |
11
Time Complexity: O(N + M)
Space Complexity: O(N + M)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!