1. 플로이드-와샬 알고리즘
•
모든 정점에서 모든 정점으로의 최단 거리를 한번에 구하는 알고리즘
•
O(N^3) 시간복잡도를 가지고 있다.
•
모든 정점쌍을 표현하는 이차원 배열을 선언하고 DP 방식으로 최단거리를 업데이트한다.
2. 플로이드-와샬 알고리즘
•
i행과 j열의 원소인 (i, j) 원소는 정점i로부터 정점j까지의 최단 경로를 뜻한다.
•
Dynamic Programming 방식으로 진행된다.
◦
점화식 distance[i,j] = min(distance[i,j], distance[i,n] + distance[n,j])
▪
정점 i에서 정점 n을 거쳐서 정점 j로 갈 때, n을 거쳐 가는 것이 더 최단경로일 경우 업데이트 한다.
▪
이렇게 거쳐갈 정점을 차례대로 모두 검사하여 업데이트 해나간다.
3. 플로이드-와샬 알고리즘 프로세스
•
행렬 초기화
◦
그래프 모양을 참고하여 초기화 한다.
◦
직접적으로 인접하여 연결되어 있지 않은 정점들의 경우 INF 무한대로 초기화 한다.
◦
자기 자신과 자기 자신이 연결되어 있진 않기 때문에 행렬의 대각선은 모두 0 이 된다.
•
거쳐갈 정점들을 처음부터 차례대로 검사하여 해당 정점을 거쳐 가는 것이 더 최단 경로일 경우 원소를 업데이트 한다. 매번 행렬 전체 원소들에 대해 진행!!
◦
ex)
▪
정점 1 을 거쳐갈 때
•
기존의 (i, j) 원소값 보다 (i, 1) + (1 + j) 값이 더 작으면 이 값으로 업데이트. 아니면 냅두기.
•
즉 ! 정점 1 을 거쳐가는게 더 최단 경로일 경우 업데이트 하는 것이다.
▪
정점 2 을 거쳐갈 때
•
기존의 (i, j) 원소값 보다 (i, 2) + (2 + j) 값이 더 작으면 이 값으로 업데이트. 아니면 냅두기.
•
기존의 (i, j)는 정점 1 을 거쳐오는 경우도 고려해서 최단 경로를 업데이트 기존에 됐던 경우다.
•
정점 2 을 거쳐가는게 더 최단 경로일 경우 업데이트 하고 아니라면 정점 2 거쳐가지 말고 기존 값 그대로 냅두기 !
▪
이런식으로 모든 정점을 거쳐가는 경우를 쭉쭉 따져서 전체 행렬 원소들을 업데이트 해나가면 된다.
3.1 BFS 시간 복잡도
모든 i, j 에 대하여 중간에 k 라는 노드를 경유하는 모든 경우의 수를 계산하는 3중 반복문의 구조를 가지고 있으므로 시간복잡도는 O(N^3)이다.
3.2. 플로이드-와샬 구현
void floid() {
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
C++
복사