# 문제
백준 11404 플로이드 파이썬 풀이
# 코드
'''
- 플로이드-워셜 알고리즘은 모든정점에서부터 모든 정점까지의 최단거리를 구하는 방법
- DISTANCE를 N*N로 만들고, 행이 시작점, 열이 도착점이 된다.
- 다익스트라는 그리디 알고리즘 적용, 플로이드 워셜은 다이나믹 프로그래밍이 녹아있음
- 구해야하는 노드의 갯수가 적으면 플로이-워셜을 사용해도 괜찮
- 거쳐가는 노드가 반복문의 중심에 있다. - 거쳐가는 노드를 반복문을 하나씩 시작함.
- 다익스트라는 매번 가장 적은 비용을 가지는 노드를 꺼내서 확인했음
- O(N^3)
- 플로이드-워셜 알고리즘
- DISTANCE테이블을 초기화 시키자 ( 연결된곳은 해당 weight, 갈 수 없느 곳은 INF )
- for pivot in range(N) :
for start in range(N) :
for end in range(N) :
'''
import sys
n = int(sys.stdin.readline().strip()) # 도시의 개수
m = int(sys.stdin.readline().strip()) # 버스의 개수
distance = [ [float('inf')] * (n+1) for _ in range(n+1)]
# 같은 정점간 중복되는 간선이 존재할 수 있음, 그럴 경우 가장 짧은 간선만 사용하면 됨.
for _ in range(m) :
a,b,c = map(int,sys.stdin.readline().split())
if c < distance[a][b] :
distance[a][b] = c
for i in range(n+1) : # 대각행렬 요소(자기 자신)는 0으로 초기화
distance[i][i] = 0
# 플로이드 워셜을 사용하여 최단거리 업데이트
for pivot in range(1,n+1) :
for start in range(1,n+1) :
for end in range(1, n+1 ) :
cost = distance[start][pivot] + distance[pivot][end]
if cost < distance[start][end] :
distance[start][end] = cost
for row in range(1,n+1) :
for col in range(1,n+1) :
if distance[row][col] == float('inf') :
print(0, end=" ")
else :
print(distance[row][col], end=" ")
print()
# 풀이
- 다익스트라는 한정점에서부터 모든정점까지의 최단거리를 구한다.
- 플로이드-와샬은 모든정점에서부터 모든정점까지의 최단거리를 구한다.
- 다익스트라는 우선순위 큐로 구현했을때 O(E*logV)의 시간복잡도를 가진다. 플로이드 와샬은 O(V^3)의 시간복잡도를 가진다.
- Edge의 상한이 V^2 이상이라면, 플로이드 와샬이 더 빠르게 된다. O ( V * V^2 * log V ) 이기 때문에 O(V^3 * log V )가 되기 때문이다. 다익스트라를 V번 돌려야 하기 때문에.
- 플로이드 와샬의 핵심 요지는 거쳐가는 노드가 중심이 되어 반복문을 돌린다.
- distance배열의 대각요소를 0으로 초기화 해주는것을 잊지 말자.
# 참고
플로이드 와샬과 다익스트라 알고리즘의 시간복잡도 비교
'•알고리즘(Algorithm ) > 문제풀이' 카테고리의 다른 글
[백준2610&파이썬] 플로이드-와샬과 유니온파인드를 함께 이용해보자. (1) | 2023.04.25 |
---|---|
[백준1613&파이썬] 플로이드 와샬 알고리즘은 모든 노드로부터 특정노드까지의 연결여부를 알 수 있다. (0) | 2023.04.25 |
[백준1162&파이썬] 다익스트라에서 distance를 여러가지로 갈래로 분리시켜야 할때 (1) | 2023.04.23 |
[백준17835&파이썬] 다익스트라로 역방향 그래프 만들어 특정노드들로부터 가장 가까운 거리 구해 확정하기 (0) | 2023.04.23 |
[백준1504&파이썬] 다익스트라에서 특정정점을 무조건 방문해야할때, 다익스트라는 시작정점으로부터 최단경로를 보장한다. (0) | 2023.04.22 |