다익스트라(Dijkstra) 알고리즘이란?
음의 가중치가 없는 그래프에서 한 정점(vertex)에서 다른 모든 정점까지 가는 최단경로를
구하는 것을 말한다.

위 그림을 기준으로 볼 때 A<->B로 볼 때 이동거리가 6이다.
이동거리를 가중치라고 표현하기도 하고 비용이라고도 하기도 한다.
다익스트라 알고리즘을 적용하려면 이동거리가 음수가 나오면 안된다는 뜻이다.
가중치가 음이 나온 경우 다익스트라 알고리즘으로 최소경로를 구할 수 없는데
그 이유는 다익스트라 알고리즘은 현재 노드를 기준으로 최소 비용인 노드로 이동하는 방식인데
음수면 그 경로를 반복해서 왔다갔다 하기도 하고
더 낮은 비용의 값이 나오면 갱신을 하는데 음의 가중치가 있으면 무한 갱신되기 때문이다.
다익스트라를 잘 이해하기 위해 예제 문제와 함께 알아보자.
백준 4485번
https://www.acmicpc.net/problem/4485
import sys
import heapq
input = sys.stdin.readline
n = int(input())
# 남,동,서,북
direction_x = [0,1,-1,0]
direction_y = [1,0,0,-1]
count = 0
while n != 0:
# 입력받기
count+=1
board = [list(map(int,input().split())) for _ in range(n)]
distance = [[float('inf')]*n for _ in range(n)]
# 최단 경로를 저장하는 최소 힙
heap = []
# 최소힙인 heap에 (board[0][0],0,0)을 넣는다.
heapq.heappush(heap, (board[0][0], 0, 0))
while heap:
# heap에서 가장 작은 값을 pop한다.
cost,x,y = heapq.heappop(heap)
# 최소 가중치를 먼저 가기 때문에 [n-1][n-1]에 도착하면 break한다.
if x==n-1 and y==n-1:
print(f"Problem {count}: {cost}")
n = int(input())
break
# 남,동,서,북으로 이동한다.
for i in range(4):
next_x = x+direction_x[i]
next_y = y+direction_y[i]
# 이동한 좌표가 범위 내에 있으면
if 0<=next_x<n and 0<=next_y<n:
# 이동한 좌표의 가중치가 현재 가중치+이동한 좌표의 가중치보다 크면
if distance[next_y][next_x] > cost+board[x][y]:
# 이동한 좌표의 가중치를 현재 가중치+이동한 좌표의 가중치로 갱신한다.
distance[next_y][next_x] = cost+board[x][y]
# heap에 (현재 가중치+이동한 좌표의 가중치,이동한 y좌표,이동한 x좌표)를 넣는다.
heapq.heappush(heap, (cost+board[next_y][next_x],next_x,next_y))
음의 가중치가 있어도 노드 간의 최단거리를 구할 수 있는 알고리즘.
시간복잡도는 정점의 갯수를 V, 간선의 갯수를 E라고 할 때 이다.
음의 가중치가 있어도 노드 간의 최단거리를 구할 수 있는 알고리즘.
시간복잡도는 정점의 갯수를 V라고할 때
파이썬으로 구현할 경우 삼중 for문으로 구현이 단순하다.
정점의 갯수를 V(Vertex), 간선의 갯수를 E(Edge)라고 할 때
| 다익스트라 | 벨만 포드 | 플로이드 와샬 | |
|---|---|---|---|
| 음수 가중치가 있을 때 | 계산 불가 | 계산 가능 | 계산 가능 |
| 시간 복잡도 | |||
| 장점 | 시간 복잡도 낮음 | 음수 계산 가능, 낮은 시간복잡도 | 음수 계산 가능,단순한 구현 |
| 단점 | 음수 계산 불가 | 복잡한 구현 | 높은 시간복잡도 |