Minimum time to reach from Node 1 to N if travel is allowed only when node is Green

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 edgeint 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 Nint 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 Codeint 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 Queuefrom queue import Queue# Function to find min edgedef 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 Ndef 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 Codeif __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 edgefunction 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 Nfunction 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 Codefunction 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 zambiatek!



