Post

[알고리즘] 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)

이것이 취업을 위한 코딩 테스트다. with 파이썬 책을 참고하여 정리한 내용입니다.

✅ 플로이드 워셜 알고리즘

플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)'모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우'에 사용할 수 있는 알고리즘이다. 해당 알고리즘은 노드의 개수가 $N$개 일 때 알고리즘상으로 N번의 단계를 수행하며, 단계마다 $O(N^2)$의 연산을 통해 ‘현재 노드를 거쳐 가는’ 모든 경로를 고려한다. 따라서 플로이드 워셜 알고리즘의 총 시간 복잡도는 $O(N^3)$이다.

플로이드 워셜 알고리즘은 2차원 리스트에 ‘최단 거리’ 정보를 저장하며, ‘점화식에 맞게’ 2차원 리스트를 갱신하기 때문에 다이나믹 프로그래밍으로 볼 수 있다. 점화식은 다음과 같다.

\[D_{ab} = min(D_{ab}, D_{ak} + D_{kb})\]

‘a에서 b로 가는 최소 비용’과 ‘a에서 k를 거쳐 b로 가는 비용’ 중 더 작은 값으로 갱신하겠다는 의미이다.

✔️ 플로이드 워셜 알고리즘 소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import sys

INF = int(1e9)  # 무한을 의미하는 값으로 10억을 설정

# 노드의 개수 및 간선의 개수를 입력받기
n = int(sys.stdin.readline())
m = int(sys.stdin.readline())

# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화
graph = [[INF] * (n + 1) for _ in range(n + 1)]

# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화
for a in range(1, n + 1):
    for b in range(1, n + 1):
        if a == b:
            graph[a][b] = 0

# 각 간선에 대한 정보를 입력받아, 그 값으로 초기화
for _ in range(m):
    # A에서 B로 가는 비용은 C라고 설정
    a, b, c = map(int, sys.stdin.readline().split())
    graph[a][b] = c

# 점화식에 따라 플로이드 워셜 알고리즘을 수행
for k in range(1, n + 1):
    for a in range(1, n + 1):
        for b in range(1, n + 1):
            graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
This post is licensed under CC BY 4.0 by the author.

[알고리즘] 다익스트라(Dijkstra) 최단 경로 알고리즘

[알고리즘] 서로소 집합