개념

플로이드 와샬 알고리즘은 다익스트라 알고리즘과 마찬가지로 최단 경로를 구할 때 사용하는 알고리즘입니다. 그러나 한 지점에서 다른 특정 지점까지 최단 거리를 구하는 다익스트라 알고리즘과 달리 플로이드 와샬 알고리즘은 모든 지점에서 다른 모든 지점까지의 경로를 구하는데 사용하는 알고리즘입니다. 플로이드 와샬 알고리즘은 어떠한 지점에서 다른 지점으로 갈 때 거쳐 가는 노드를 탐색한 후 distance 리스트를 갱신하는 식으로 구현합니다. 플로이드 와샬 알고리즘의 경우 구현이 다익스트라에 비해 쉽다는 단점이 있지만 O(ElogV)의 시간 복잡도를 가지는 다익스트라 알고리즘과 달리 O(N^3)의 시간 복잡도를 가지기 때문에 사용할 수 있는 조건이 매우 한정적입니다. 따라서 문제에서 주어진 N의 범위를 잘 확인한 후 어떤 알고리즘을 사용할지 결정을 해야 합니다.  그럼 그림을 통해 알아봅시다.

나동빈님의 이것이 취업을 위한 코딩테스트이다 그림을 참고하였습니다.

먼저 이차원 리스트를 만든 후 모든 원소에 대해서 무한으로 초기화를 합니다. 그 후 자기 자신의 노드로 가는 최단 경로는 0 이기 때문에 0을 대입해 줍니다. 또한 각각의 노드에서 이동할 수 있는 노드들에 거리를 대입해 줍니다. 그러면 다음과 같은 표가 만들어 집니다. 

  1 2 3 4
1 0 4 INF 6
2 3 0 7 INF
3 5 INF 0 4
4 INF INF 2 0

 

그 후 거쳐가는 노드들을 고려해 줍니다. 예를 들어 1번 노드에서 3번 노드로 가는 경우를 봅시다. 위의 표에서 해당 하는 칸은 즉 1행 3열은 INF로 초기화가 되어있습니다. 그러나 1번 노드에서 4번 노드를 거친 후 3번 노드로 가면 8 이라는 경로가 나오게 됩니다. 따라서 이런 식으로 어떠한 노드에서 다른 노드로 갈 때 거쳐가는 노드를 확인한 후 최솟값으로 대입을 해주면 다음과 같습니다. 

  1 2 3 4
1 0 4 8 6
2 3 0 7 9
3 5 9 0 4
4 7 11 2 0

소스코드

 

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
INF = int(1e9)
 
= 4
= 7
graph = [[INF] * (1+n) for _ in range(1+n)]
 
for i in range(11 + n):
  for j in range(11 + n):
    if i == j:
      graph[i][j] = 0
 
for _ in range(m):
  a, b, c = map(int, input().split())
  graph[a][b] = c
 
for k in range(11 + n):
  for a in range(11 + n):
    for b in range(11 + n):
      graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
 
for i in range(11 + n):
  for j in range(11 + n):
    if graph[a][b] == INF:
      print("INF", end=" "
    else:
      print(graph[i][j], end=" ")
  print()
cs

+ Recent posts