We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Second Minimum Time to Reach Destination

Difficulty: Hard


Problem Description

Given a city represented as a bi-directional connected graph with n vertices, find the second minimum time it takes to go from vertex 1 to vertex n. Each vertex has a traffic signal that changes color every change minutes. You can only leave a vertex when the signal is green, and you cannot wait at a vertex if the signal is green.


Key Insights

  • The problem requires finding both the minimum and second minimum time to reach the destination.
  • The graph can be traversed using BFS or Dijkstra's algorithm, modified to account for waiting times at vertices.
  • Each vertex can be revisited multiple times, allowing for different paths and waiting scenarios.
  • The time spent waiting at a vertex is determined by the traffic signal's state and the time taken to cross each edge.

Space and Time Complexity

Time Complexity: O(E * log(V)) for Dijkstra-like traversal, where E is the number of edges and V is the number of vertices. Space Complexity: O(V) for storing the graph and distances.


Solution

To solve this problem, we can use a modified Dijkstra's algorithm. We will maintain a priority queue to explore paths, keeping track of the minimum and second minimum times to reach each vertex. When traversing, we need to account for the waiting time at each vertex based on the signal's state.

  1. Create a graph representation using an adjacency list.
  2. Use a priority queue to manage exploration of paths based on time.
  3. For each vertex, track the minimum and second minimum time.
  4. While exploring edges, calculate the time spent waiting at the current vertex if necessary.
  5. Push new times into the priority queue until we find the second minimum time to reach the target vertex.

Code Solutions

import heapq
from collections import defaultdict

def secondMinimum(n, edges, time, change):
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)
    
    # Min times to each node
    min_times = [[float('inf'), float('inf')] for _ in range(n + 1)]
    min_times[1][0] = 0
    pq = [(0, 1, 0)]  # (current_time, node, which_time)
    
    while pq:
        current_time, node, which_time = heapq.heappop(pq)
        
        # If we reached the final node with the second minimum time
        if node == n and which_time == 1:
            return current_time
        
        for neighbor in graph[node]:
            travel_time = current_time + time
            # Calculate the next signal state
            wait_time = (current_time // change + 1) * change - current_time
            
            # If we enter and find the signal red, wait
            if current_time % change >= change // 2:
                travel_time += wait_time
            
            # Update the min times for the neighbor
            if travel_time < min_times[neighbor][0]:
                min_times[neighbor][1] = min_times[neighbor][0]
                min_times[neighbor][0] = travel_time
                heapq.heappush(pq, (travel_time, neighbor, 0))
            elif min_times[neighbor][0] < travel_time < min_times[neighbor][1]:
                min_times[neighbor][1] = travel_time
                heapq.heappush(pq, (travel_time, neighbor, 1))
    
    return -1  # If unreachable
← Back to All Questions