Open In App

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

Last Updated : 08 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.


Output

11

Time Complexity: O(N + M)
Space Complexity: O(N + M)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads