input: from typing import List
  from heapq import heappop, heappush
  
  def calculate_minimum_reach_time(n: int, links: List[List[int]], vanish: List[int]) -> List[int]:
      """
      Consider an undirected network with n vertices. The input is a 2D list 'links', where each links[i] = [ui, vi, durationi] indicates a connection between vertices ui and vi with a travel time of durationi units.
  
      Additionally, a list 'vanish' is given, where vanish[i] represents the time when the vertex i is not accessible anymore.
  
      Note that the network may be disconnected and there can be multiple links.
  
      Return a list result, where result[i] indicates the least amount of time to reach vertex i from vertex 0. If vertex i cannot be reached from vertex 0, then result[i] is -1.
  
      Test cases:
      >>> calculate_minimum_reach_time(3, [[0,1,2],[1,2,1],[0,2,4]], [1,1,5])
      [0,-1,4]
      >>> calculate_minimum_reach_time(3, [[0,1,2],[1,2,1],[0,2,4]], [1,3,5])
      [0,2,3]
      >>> calculate_minimum_reach_time(2, [[0,1,1]], [1,1])
      [0,-1]
  
      Constraints:
      1 <= n <= 5 * 10^4
      0 <= links.length <= 10^5
      links[i] == [ui, vi, durationi]
      0 <= ui, vi <= n - 1
      1 <= durationi <= 10^5
      vanish.length == n
      1 <= vanish[i] <= 10^5
      """
output:     
      import heapq
      from collections import defaultdict
      import sys
  
      graph = defaultdict(list)
      for u, v, duration in links:
          graph[u].append((v, duration))
          graph[v].append((u, duration))
  
      result = [-1] * n
      min_heap = [(0, 0)]  # (time, node)
      visited = [False] * n
      while min_heap:
          time, node = heapq.heappop(min_heap)
          if visited[node] or time >= vanish[node]:
              continue
          visited[node] = True
          result[node] = time
          for neighbor, duration in graph[node]:
              if not visited[neighbor]:
                  heapq.heappush(min_heap, (time + duration, neighbor))
      
      return result
  