문제
방향그래프가 주어지면 주어진 시작점에서 다른 모든 정점으로의 최단 경로를 구하는 프로그램을 작성하시오. 단, 모든 간선의 가중치는 10 이하의 자연수이다.
입력
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가 주어진다. 셋째 줄부터 E개의 줄에 걸쳐 각 간선을 나타내는 세 개의 정수 (u, v, w)가 순서대로 주어진다. 이는 u에서 v로 가는 가중치 w인 간선이 존재한다는 뜻이다. u와 v는 서로 다르며 w는 10 이하의 자연수이다. 서로 다른 두 정점 사이에 여러 개의 간선이 존재할 수도 있음에 유의한다.
출력
첫째 줄부터 V개의 줄에 걸쳐, i번째 줄에 i번 정점으로의 최단 경로의 경로값을 출력한다. 시작점 자신은 0으로 출력하고, 경로가 존재하지 않는 경우에는 INF를 출력하면 된다.
내 풀이
import sys
import heapq
input = sys.stdin.readline
n, m = map(int, input().split())
start = int(input())
graph = [[] for _ in range(n+1)]
for _ in range(m):
u, v, w = map(int, input().split())
graph[u].append([v, w])
def dijkstra(graph, start):
distances = [float('inf')]*(n+1)
distances[start] = 0
q = []
heapq.heappush(q, [distances[start], start])
while q:
dist, node = heapq.heappop(q)
if distances[node] < dist:
continue
for next_node, next_dist in graph[node]:
distance = dist + next_dist
if distance < distances[next_node]:
distances[next_node] = distance
heapq.heappush(q, [distance, next_node])
return distances
answer = dijkstra(graph, start)
for i in range(1, n+1):
if answer[i] == float('inf'):
print('INF')
else:
print(answer[i])
= 정점의 개수, = 간선의 개수
시간 복잡도 →
heappush
,heappop
시에 만큼의 시간 복잡도 소요while q:
반복문을 돌면서heappop
이 최대 번 실행 →for next_node, next_dist in graph[node]:
간선의 개수만큼 탐색하여heappush
가 번 실행 →공간 복잡도 →
graph
의 공간 복잡도
코멘트
그래프에 최단 경로를 찾는 문제라서 BFS를 사용해야겠다고 생각했는데 단방향 그래프인데다가 간선 별로 가중치가 달라서 어떻게 풀어야할지 고민을 많이 했다ㅠ 찾아보니 다익스트라 알고리즘을 활용하는 문제였고, 그래서 같은 유형인 백준 1916 최소 비용 구하기 문제를 참고하여 풀었다.
다익스트라 알고리즘은 heap을 이용해서 푸는 것이 핵심이다. 우선 그래프를 입력받을 때 graph[노드 A].append([노드 B, weight])
와 같은 형태로 노드 A에서 노드 B로 가는 가중치를 저장한다. 그리고 거리 정보를 입력할 리스트를 초기화해두고 BFS처럼 시작 지점을 heap에 입력한다. 그리고 heapop하여 꺼낸 후 다음에 이동할 노드까지의 거리를 갱신한다. 이 과정을 while 문으로 반복하다보면 해당 노드까지의 최단 거리가 기록되고, 이를 출력하면 되는 문제이다. (inf로 남아있으면 가는 방법이 없으므로 INF
를 출력하도록)
이 문제를 풀 때 변수명이 겹치도록 유의하자. 이 문제에서 정점의 개수를 V로 제시하고 간선과 간선 사이의 가중치를 u, v, w로 제시하고 있는데 별 생각없이 모두 소문자로 썼다가 v 값이 갱신되어서 자꾸만 그래프 탐색이 끝까지 이뤄지지 않는 문제가 생겨서 이거 발견하는데 몇 시간을 날렸다....
References
https://www.acmicpc.net/problem/1753
![[백준] 1916 최소비용 구하기](https://images.velog.io/velog.png)