티스토리 뷰
The Floyd-Warshall Algorithm
모든 정점 쌍에 대해 둘 사이의 최단 거리를 구하는 알고리즘
- Dijkstra/Bellman-Ford 를 반복해서 구할 수도 있음
경유점 : 두 정점 u와 v를 잇는 어떤 경로가 있다고 가정할 때, u와 v 사이에 있는 다른 정점
1. 경유점 k를 제외한 S - {k} 노드 중 서로 다른 노드 U, V 선택 (S = 정점 집합일 때 k, U, V ∈ S)
2. U → k → V의 비용 확인 후 최단거리 갱신
직접 해보기
다음과 같은 그래프가 주어졌다고 해보자.
Floyd-Warshall 알고리즘은 Dijkstra와 다르게 모든 그래프의 모든 정점 쌍의 최단 거리를 저장해야하므로 2차원 배열이 필요하다
초기화 할 때에는
- if from == to, then 0
- if edge(from, to) == value then value, else infinity
![](https://i.imgur.com/khUGC2k.png)
초기화가 완료되었으면 모든 정점들을 '경유점'으로 만들어 가며 2차원 배열을 갱신해나간다.
아래와 같이 A가 경유점이 되었다면, 나머지 정점쌍에 대해 거리를 비교하며 표를 갱신할 수 있다.
예를 들어 기존 BD간 거리는 정의되어 있지 않아 infinity였는데 A를 경유하면서 거리가 9로 짧아졌으므로 갱신한다.
위 과정을 보면 모든 정점에 대해 경유점을 선택하고 모든 시작점과 끝점을 선택하는 과정에서 3중 for문이 도는 것을 알 수 있다.
이를 코드로 작성해보면 아래와 같다.
graph = [[Int]]()
func floydWarshall() {
for k in 0..<n {
for from in 0..<n {
for to in 0..<n {
graph[from][to] = min(graph[from][k] + graph[k][to], graph[from][to])
}
}
}
}
가장 충실하게 짜여진 코드지만 문제에 따라 최적화의 필요는 있다.
- 실제 from 노드에서 경유 노드로 간선이 있는지 확인
- Undirected Graph라면 대각선 상위로만 적용
시간 복잡도
노드의 개수가 N개 일 때 한 노드마다 O(N²)의 연산을 수행하므로 O(N³)
문제를 뽀샤버려라
- 백준 다익스트라 모음 : 열로가쑈
- 프로그래머스 : 순위(49191)
'CS > 알고리즘' 카테고리의 다른 글
[Swift] 코딩테스트 때 쓸 문법 (0) | 2021.01.01 |
---|---|
최단거리 알고리즘 ❶ Dijkstra Algorithm (0) | 2020.12.29 |
[C++] 코딩 테스트 때 쓸 코드 (1) | 2020.07.03 |
[프로그래머스] 스킬트리 (배열) (0) | 2020.07.02 |
[프로그래머스] 멀쩡한 사각형 (일차함수 & 자료형) (0) | 2020.07.02 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- ios
- firebase
- TableView
- 소프트웨어아카데미
- 부스트캠프2020
- 컴과졸작
- 인턴
- OS
- 삼성
- C++
- 소프트웨어역량시험
- 컴공졸작
- 컴퓨터공학
- 코테
- 삼성소프트웨어아카데미
- 알고리즘
- swacademy
- 부캠
- SWIFT
- 커넥트재단
- 보안
- RxSwift
- 졸업작품
- 데이터분석
- 개발자인턴
- 부스트캠프
- 프로그래머스
- nosql
- 운영체제
- 코딩테스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함