- 하나의 정점에서 다른 모든 정점까지의 최단 경로를 구하는 알고리즘
- 다익스트라
- 음의 가중치로 인한 싸이클 발생 판별 불가능
- 현재까지 탐색된 정점 집합에서 최단 경로를 가지고 있는 탐색되지 못한 정점을 찾아 탐색한 정점 집합에 추가한다.
- 그 다음, 탐색된 정점(i)들에 대해 새로 추가한 정점(j)을 거칠 때 발생하는 최단 경로를 업데이트한다.
: D[i] = min(D[i], D[j] + W[j][i])
- 반복한다
- 기본문제
https://www.acmicpc.net/problem/17531753번: 최단경로
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1≤V≤20,000, 1≤E≤300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1≤K≤V)가 주어진다.
www.acmicpc.net
- 벨만포드
- 음의 가중치로 인한 싸이클 발생 판별 가능
- 최단경로는 순환을 포함해서는 안되므로 경로의 길이는 최대 |N-1| 임을 이용한다
- 즉, 모든 edge에 대해 |V-1|번만큼 최단경로 업데이트를 해준 뒤에, 또 업데이트가 발생하면 음의 가중치가 있다는 것을 이용한다
for(int i=0; i<N-1; i++){ for(int j=0; j<edge.size(); j++){ int src, dest, cost = src, dest, cost of edge j; if(D[src] != INF && D[dest] > D[src] + cost) D[dest] = D[src] + cost; } } for(int j=0; j<edge.size(); j++){ int src, dest, cost = src, dest, cost of edge j; if(D[dest] > D[src] + cost) cout << "there is infinite loop\n"; }
N : 정점 개수
V[] : 탐색한 정점 집합
s : 시작 정점
W[][] : 인접행렬
D[] : s부터 다른 정점까지의 최단 경로
- 다익스트라
- 모든 최단 경로를 구하는 알고리즘 : 플로이드-와샬
- 모든 점에 대해 중간 정점으로 취했을 때 최단경로가 발생하면 업데이트함으로써, 모든 정점 간 최단 경로를 구하는 알고리즘
: W[i][j] = min(W[i][j], W[i][k] + W[k][j])
W[][] : 인접행렬
- 기본문제
https://www.acmicpc.net/problem/11404
11404번: 플로이드
첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가
www.acmicpc.net
- 하나의 목적지로가는 모든 최단 경로를 구하는 알고리즘
- one to all edge graph를 뒤집으면 된다 - 하나의 정점에서 다른 하나의 정점까지의 최단 경로를 구하는 알고리즘
- 다익스트라 알고리즘보다 비효율적
'알고리즘 > 알고리즘풀면서...' 카테고리의 다른 글
문자열 알고리즘관련 (0) | 2022.05.08 |
---|---|
다시 풀어볼만한 문제 모음 (1) | 2021.10.03 |
C/C++ 팁 (0) | 2020.11.04 |
구현 팁 (0) | 2020.10.31 |
SQL 팁 (0) | 2020.10.22 |