728x90
플로이드 워셜 알고리즘
: 모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우에 사용하는 알고리즘
- 모든 노드에 대하여 다른 모든 노드로가는 최단 거리 정보를 담아야 하기 때문에 2차원 리스트에 '최단 거리' 정보를 저장함 => N번의 단계에서 매번 O(N^2)의 시간이 소요됨.
- 각 단계에서는 해당 노드를 거쳐가는 경우를 고려함.
ex) 1번 노드에 대해 확인할 때: A -> 1번 노드 -> B로 가는 비용 확인한 후 최단 거리 갱신
=> O(N^3)
- 다이나믹 프로그래밍
점화식: Dab = min (Dab, Dak+Dkb)
(Dab = a에서 b로 가는 최단 거리)
출발|도착 | 1번 | 2번 | 3번 | 4번 |
1번 | 0 | 4 | 무한 | 6 |
2번 | 3 | 0 | 7 | 무한 |
3번 | 5 | 무한 | 0 | 4 |
4번 | 무한 | 무한 | 2 | 0 |
[Step0]
이런 그래프가 있을때, 다음처럼 초기 테이블을 설정할 수 있다.
[Step1]
1번 노드를 거쳐 가는 경우를 고려한다.
D23 = min (D23, D21 + D13)
D24 = min (D24, D21 + D14)
D32 = min (D32, D31 + D12)
D34 = min (D34, D31 + D14)
D42 = min (D42, D41 + D12)
D43 = min (D43, D41 + D13)
0 | 4 | 무한 | 6 |
3 | 0 | ||
5 | 0 | ||
무한 | 0 |
[Step2]
2번 노드를 거쳐 가는 경우를 고려한다.
.
.
.
[Step4]
4번 노드를 거쳐 가는 경우를 고려한다.
# 플로이드 워셜 알고리즘 (O(N^3))
INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정
# 노드의 개수 및 간선의 개수를 입력 받기
n = int(input())
m = int(input())
# 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, input().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])
# 수행된 결과를 출력
for a in range(1, n+1):
for b in range(1, n+1):
# 도달할 수 없는 경우, 무한(INFINITY)이라고 출력
if graph[a][b] == INF:
print("INFINITY", end=" ")
# 도달할 수 있는 경우, 거리를 출력
else:
print(graph[a][b], end=" ")
print()
'''
입력 예시
4
7
1 2 4
1 4 6
2 1 3
2 3 7
3 1 5
3 4 4
4 3 2
출력 예시
0 4 8 6
3 0 7 9
5 9 0 4
7 11 2 0
'''
728x90
'Programming > Algorithm' 카테고리의 다른 글
[Algorithm] 신장 트리(최소 신장 트리, 크루스칼 알고리즘) (0) | 2021.09.15 |
---|---|
[Algorithm] 서로소 집합 (0) | 2021.09.15 |
[Algorithm] 다익스트라 최단 경로 알고리즘 (0) | 2021.08.21 |
[Algorithm] DFS/BFS (0) | 2021.08.12 |
[Algorithm] 다이나믹 프로그래밍 (0) | 2021.07.22 |