반응형

오늘 설명할 알고리즘은 플로이드 와샬 알고리즘(Floyd Warshall Algorithm)입니다. 이 알고리즘은 dijkstra와 비슷하게 각 정점까지 가는 최단 거리를 알아낼 수 있습니다. 플로이드 와샬 알고리즘 dijkstra보다 시간은 더 오래 걸리지만 모든 노드들 간의 최단 거리를 알아낼 수 있습니다.

 

[ 동작 원리 ]

 

  1. 시작 정점, 중간에 거쳐갈 정점 그리고 도착 정점을 선택합니다.
  2. 만약 시작 정점부터 도착 정점까지 거리보다 시작 정점 - 중간 정점 - 도착 정점까지의 거리가 더 짧다면 값을 경신시켜줍니다.

 

플로이드 와샬 알고리즘의 동작 과정을 그림으로 이해해 봅시다.

 

 

위와 같은 그래프가 존재할 때 각 정점에서부터 정점에서까지의 거리를 2차원 배열로 나타내면 다음과 같습니다.

 

 

위의 2차원 배열이 나타내는 것은 바로 현재까지 계산된 각 노드에서 노드까지의 최소 비용입니다. 이를 3중 for문을 이용하여 모든 노드들에 대해 값을 경신해나가면 마지막에는 특정 노드에서 노드까지의 최소 비용을 모두 구할 수 있습니다.

 

먼저 노드 1을 거쳐가는 경우는 다음과 같습니다.

 

 

노드 1을 거쳐가는 경우에는 위의 6개의 값만 경신시켜주면 됩니다. 이때 시작 노드와 도착 노드까지의 거리시작 노드 - 중간 노드 - 도착 노드까지의 거리 중 더 짧은 거리로 갱신시켜주면 됩니다.

 

위의 과정을 거치면 다음과 같은 결과를 얻을 수 있습니다.

 

 

이런 방법으로 1번부터 4번 노드까지 모두 값을 갱신해주면 다음과 같은 결과를 얻을 수 있습니다.

 

 

[ 소스 코드 ]

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
 
using namespace std;
 
int n, m;
long long cost[101][101];
 
int main()
{
    cin >> n >> m;
 
    for (int i = 1; i <= n; i++) {            //출발지와 도착지가 같을 때 0으로 초기화
        for (int j = 1; j <= n; j++) {        //아니라면 INF로 초기화
            if (i == j) {
                cost[i][j] = 0;
            }
            else {
                cost[i][j] = 99999999999;
            }
        }
    }
 
    for (int i = 0; i < m; i++) {            //출발지와 도착지가 같은 간선이 여러개일 때
        int a, b, c;                        //가장 짧은 거리로 초기화
        scanf("%d %d %d"&a, &b, &c);
        if (cost[a][b] > c) {
            cost[a][b] = c;
        }
    }
 
    for (int k = 1; k <= n; k++) {            //거쳐가는 노드
        for (int i = 1; i <= n; i++) {        //출발 노드
            for (int j = 1; j <= n; j++) {    //도착 노드
                if (cost[i][j] > cost[i][k] + cost[k][j]) {
                    cost[i][j] = cost[i][k] + cost[k][j];
                }
            }
        }
    }
 
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cout << cost[i][j] << " ";
        }
        cout << endl;
    }
}
cs
반응형

+ Recent posts