카테고리 없음
[LeetCode] 3123. Find Edges in Shortest Paths (Python)
이준언
2024. 11. 17. 22:11
안녕하세요!
오늘은 leetcode 3123번 Find Edges in Shortest paths 문제를 풀어보겠습니다.
0~n-1 로 넘버링되어있는 n개의 노드를 가진 그래프가 있습니다. 이 그래프는 2d 배열인 'edges'로 대표되는 m edges로 이루어져 있는데요, edges[i] = [ai, bi, wi] 로 표현될 수 있고, 이는 노드 ai, bi간의 가중치 wi를 의미합니다. 0에서 n-1 노드 까지의 모든 최단 경로 중에서, edges[i] 가 포함되면 True, 그렇지 않으면 False를 출력하는 함수를 작성하는 문제입니다. 모든 결과를 'answer' 배열에 저장하고 출력해주면 됩니다.
이 문제도 이전 시간에 풀었던 문제와 마찬가지로 Dijkstra 알고리즘을 활용해서 문제를 풀어보겠습니다.
시작 노드에서 모든 노드까지의 최단 거리를 먼저 계산해줍니다. 이 과정에서 'parents'에 최단 경로 상의 노드를 저장해줍니다. 또 최단 경로에 포함된 edges를 stack이라는 리스트에 저장해줍니다. 마지막으로 real_edges를 통해 모든 엣지에 대해 최단 경로에 포함되는지 여부를 확인하고 answer에 T/F 결과를 추가해줍니다.
import heapq
class Solution(object):
def findAnswer(self, n, edges):
"""
:type n: int
:type edges: List[List[int]]
:rtype: List[bool]
"""
# 그래프 표현
graph = {i: [] for i in range(n)}
for a, b, w in edges:
graph[a].append((b, w))
graph[b].append((a, w)) # undirected
# 부모 노드 추적 - 각 노드로 가는 최단 경로의 부모 노드 저장
parents = {i: [] for i in range(n)}
# 최단 거리 계산
distance = [float('inf')] * n
distance[0] = 0 # 시작 노드
q = [(0, 0)] # 거리, 노드
while q:
dist, node = heapq.heappop(q)
# 현재 탐색할 노드까지 거리가 기존에 저장된 거리보다 크면 스킵
if dist > distance[node]:
continue
# 인접 노드까지의 거리가 기존에 저장된 거리보다 짧으면 업데이트
for neighbor, weight in graph[node]:
new_dist = dist + weight
if new_dist < distance[neighbor]:
distance[neighbor] = new_dist
parents[neighbor] = [node] # 새로운 최단 경로로 업데이트
heapq.heappush(q, (new_dist, neighbor))
elif new_dist == distance[neighbor]:
parents[neighbor].append(node) # 최단 거리가 여러 개일 경우 고려
# 최단 경로에 포함된 edges
# 최단 경로라면 경로가 중복되면 안되므로 이를 방지하고,
# 포함 여부를 빠르게 확인하기 위해 집합 활용
real_edges = set()
stack = [n-1] # 목표 노드에서 최단 경로 역추적
visited = set() # 방문한 노드 처리
while stack:
node = stack.pop() # 스택에서 노드를 꺼내 처리
if node in visited: # 이미 방문한 노드는 스킵
continue
visited.add(node)
for parent in parents[node]: # 최단 경로 부모 노드들 확인 후 추가
real_edges.add((parent, node))
real_edges.add((node, parent))
if parent not in visited:
stack.append(parent)
# answer
answer = []
for a, b, w in edges:
answer.append((a, b) in real_edges or (b, a) in real_edges)
return answer
매우 어렵다!