알고리즘

[Algorithm] Dijkstra

parkjbdev 2025. 5. 3. 20:10

예시

초기화

노드: (다른 노드, 거리)
1: (2, 7), (3, 9), (6, 14)
2: (1, 7), (3, 10), (4, 15)
3: (1, 9), (2, 10), (4, 11), (6, 2)
4: (2, 15), (3, 11), (5, 6)
5: (4, 6), (6, 9)
6: (1, 14), (3, 2), (5, 9)

Step by Step

편의상 distance 배열의 index는 1부터 시작한다고 하자.
Q는 Min Heap Priority Queue로, (cost, node)와 같이 저장한다.

초기상태

Q = [(0, 1)]
S = {}
distance = [0, inf, inf, inf, inf]

1단계: 노드 1 방문

Q = [(0, 1)]
S = {}

pop Q & add to S
S = {1}

인접 노드들 처리

  • 2번: distance[2] = inf > 7 → 업데이트 및 push
  • 3번: distance[3] = inf > 9 → 업데이트 및 push
  • 6번: distance[6] = inf > 14 → 업데이트 및 push

Q = [(7, 2), (9, 3), (14, 6)]
distance = [0, 7, 9, inf, inf, 14]

2단계: 노드 2 방문

Q = [(7, 2), (9, 3), (14, 6)]
S = {1}

pop Q & add to S
S = {1, 2}

인접 노드들 처리

  • 1번: 무시
  • 3번: distance[3] = 9 < 7 + 10 → 무시
  • 4번: distance[4] = inf < 7 + 15 = 22 → 업데이트 및 push

Q = [(9, 3), (14, 6), (22, 4)]
distance = [0, 7, 9, 22, inf, 14]

3단계: 노드 3 방문

Q = [(9, 3), (14, 6), (22, 4)]
S = {1, 2}

pop Q & add to S
S = {1, 2, 3}

인접 노드들 처리

  • 1번: 무시
  • 2번: 무시
  • 4번: distance[4] = 22 > 9 + 11 = 20 → 업데이트 및 push
  • 6번: distance[6] = 14 > 9 + 2 = 11 → 업데이트 및 push

Q = [(11, 6), (14, 6), (22, 4), (20, 4)]
distance = [0, 7, 9, 20, inf, 11]

4단계: 노드 6 방문

Q = [(11, 6), (14, 6), (22, 4), (20, 4)]
S = {1, 2, 3}

pop Q & add to S
S = {1, 2, 3, 6}

인접 노드들 처리

  • 1번: 무시
  • 3번: 무시
  • 5번: distance[5] = inf > 11 + 9 = 20 → 업데이트 및 push

Q = [(14, 6), (20, 4), (22, 4), (20, 5)]
distance = [0, 7, 9, 20, 20, 11]

5단계: 노드 6 다시 등장 (중복)

Q = [(14, 6), (20, 4), (22, 4), (20, 5)]
S = {1, 2, 3, 6}

pop Q & add to S → 이미 S에 존재하므로 무시

Q = [(20, 4), (20, 5), (22, 4)]

6단계: 노드 4 방문

Q = [(20, 4), (20, 5), (22, 4)]
S = {1, 2, 3, 6}

pop Q & add to S
S = {1, 2, 3, 4, 6}

인접 노드들 처리

  • 2번: 무시
  • 3번: 무시
  • 5번: distance[5] = 20 ≤ 20 + 6 = 26 → 무시

Q = [(20, 5), (22, 4)]
distance = [0, 7, 9, 20, 20, 11]

7단계: 노드 5 방문

Q = [(20, 5), (22, 4)]
S = {1, 2, 3, 4, 6}

pop Q & add to S
S = {1, 2, 3, 4, 5, 6}

인접 노드들 처리

  • 4번: 무시
  • 6번: 무시

Q = [(22, 4)]

8단계: 노드 4 중복 등장 → 무시

Q = [(22, 4)]
S = {1, 2, 3, 4, 5, 6}

pop Q → 이미 S에 있으므로 무시

단계별 실행 표

단계 방문 노드 Q 상태 S distance[]
1 1 [] {1} [0, 7, 9, inf, inf, 14]
2 2 [(9,3), (14,6), (22,4)] {1,2} [0, 7, 9, 22, inf, 14]
3 3 [(11,6), (14,6), (22,4), (20,4)] {1,2,3} [0, 7, 9, 20, inf, 11]
4 6 [(14,6), (20,4), (22,4), (20,5)] {1,2,3,6} [0, 7, 9, 20, 20, 11]
5 6 (중복) [(20,4), (20,5), (22,4)] {1,2,3,6} [0, 7, 9, 20, 20, 11]
6 4 [(20,5), (22,4)] {1,2,3,4,6} [0, 7, 9, 20, 20, 11]
7 5 [(22,4)] {1,2,3,4,5,6} [0, 7, 9, 20, 20, 11]
8 4 (중복) [] {1,2,3,4,5,6} [0, 7, 9, 20, 20, 11]

[코드] Dijkstra with Priority Queue

# Dijkstra Algorithm with Adjacent List and Priority Heap
# https://www.acmicpc.net/problem/1753

from math import inf
from heapq import heappush as push, heappop as pop

# 입력
V, E = map(int, input().split())
K = int(input()) - 1 # 시작 정점 번호
EDGES = [tuple(map(int, input().split())) for _ in range(E)]

# Adjacent List
ADJ_EDGES = [[] for _ in range(V)]

for edge in EDGES:
    ADJ_EDGES[edge[0] - 1].append((edge[2], edge[1] - 1))

# Distance
distance = [inf for _ in range(V)]
distance[K] = 0

# Priority Heap: 거리순으로 정렬
pq = []
push(pq, (0, K))

while pq:
    # 노드 방문
    cost, vertex = pop(pq)
    if distance[vertex] < cost:
        continue

    # 가장 작은 weight 가진 곳으로..
    for next_c, next_v in ADJ_EDGES[vertex]:
        cmp_distance = distance[vertex] + next_c
        if cmp_distance < distance[next_v]:
            distance[next_v] = cmp_distance
            push(pq, (cmp_distance, next_v))

print(*map(lambda x: str(x).upper(), distance), sep="\n")

'알고리즘' 카테고리의 다른 글

[Algorithm] MST: Kruskal & Prim  (0) 2025.05.03