오늘 문제는 가중치가 존재하는 상황에서 최단 경로를 구하는 문제입니다. 한 번 살펴볼까요?
You are given a network of n
nodes, labeled from 1
to n
. You are also given times
, a list of travel times as directed edges times[i] = (ui, vi, wi)
, where ui
is the source node, vi
is the target node, and wi
is the time it takes for a signal to travel from source to target.
We will send a signal from a given node k
. Return the minimum time it takes for all the n
nodes to receive the signal. If it is impossible for all the n
nodes to receive the signal, return -1
.
Example 1:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2
Example 2:
Input: times = [[1,2,1]], n = 2, k = 1
Output: 1
Example 3:
Input: times = [[1,2,1]], n = 2, k = 2
Output: -1
Constraints:
1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
(ui, vi)
are unique. (i.e., no multiple edges.)주어진 네트워크에는 n개의 노드가 있으며, 이는 1부터 n까지 레이블이 주어져 있습니다. 또한 리스트가 주어집니다. 이 리스트에서 노드는 소스 노드, 는 타겟 노드, 는 노드에서 신호를 보내서 노드에 도달하는데 걸리는 시간을 의미합니다.
k 노드에서 신호를 보낼 때, 모든 노드에 신호가 도달하기 위한 최소 비용을 반환하시오. 하나의 노드라도 도달하지 못한다면 -1을 반환하시오. (한 노드에서 연결된 여러 개의 edge에 신호를 동시에 전달할 수 있습니다.)
문제가 길지만, 핵심만 보면 되게 직관적으로 표현이 된 문제입니다. 그럼 더 자세히 보겠습니다.
주어진 문제는 가중치가 있는 방향 그래프에서 단일 시작점으로부터 모든 노드에 신호가 도달하는 최소 시간을 계산하는 문제입니다. 이를 통해 특정 시작점에서 다른 노드로의 최단 경로를 찾는 알고리즘이 필요합니다.
(u, v, w)
형태로 제공되며, 이는 노드 u
에서 노드 v
로 가는 가중치 w
의 간선이 존재함을 의미합니다.k
에서 출발하여 모든 노드로 신호를 전달할 수 있어야 합니다.1
을 반환합니다.O(E)
(간선의 개수만큼 작업)O(E log E)
(우선순위 큐에 간선을 삽입하고 삭제하는 작업)defaultdict
를 사용해 인접 리스트 형태로 그래프를 생성합니다.(2, 3, 1)
은 노드 2
에서 노드 3
으로 가는 가중치가 1
임을 나타냅니다.heapq
)을 사용하여 노드 방문 순서를 결정합니다.k
의 가중치를 0
으로 설정하고 큐에 추가합니다.costs
에 포함되어 있다면, costs.values()
에서 최대 값을 반환합니다.1
을 반환합니다.from heapq import heappush, heappop
from collections import defaultdict
class Solution(object):
def networkDelayTime(self, times, n, k):
# https://leetcode.com/problems/network-delay-time/submissions/1462136700
"""
:type times: List[List[int]]
:type n: int
:type k: int
:rtype: int
"""
graph = defaultdict(list)
for time in times:
graph[time[0]].append((time[2], time[1]))
pq = []
heappush(pq, (0, k))
costs = {}
while pq:
cur_cost, cur_node = heappop(pq)
if cur_node not in costs:
costs[cur_node] = cur_cost
for cost, next_node in graph[cur_node]:
next_cost = cur_cost + cost
heappush(pq,(next_cost, next_node))
for i in range(1, n + 1):
if i not in costs:
return - 1
return max(costs.values())
코드 설명:
graph
는 인접 리스트 형태로 생성되며, 각 노드의 간선과 가중치 정보를 저장합니다.pq
를 사용해 가중치가 가장 작은 노드를 우선적으로 처리합니다.costs
딕셔너리에 n
개의 노드가 모두 포함되어 있다면, 모든 노드에 신호가 도달한 것입니다.1
을 반환합니다.시간 복잡도:
O(E)
O(E log E)
O(n)
max(costs.values())
를 호출하여 모든 노드의 도달 시간을 순회하며 최댓값을 찾습니다.costs
는 최대 n개의 노드에 대해 도달 시간을 저장하고 있으므로 이 연산의 시간 복잡도는 입니다.결과: https://leetcode.com/problems/network-delay-time/submissions/1462136700
이 문제를 통해 다익스트라 알고리즘을 활용한 가중치 그래프에서의 최단 경로 탐색을 복습할 수 있었습니다. 특히 우선순위 큐(힙)를 활용하여 최적의 시간 복잡도로 문제를 해결하는 방법을 다시 확인했습니다.
전체 코드는 다음 링크에서 확인할 수 있습니다.
역시 연습만이 살 길입니다!!
읽어주셔서 감사합니다.
매일 매일 발전하는 개발자!