dijkstra(다익스트라) 알고리즘
dijkstra graph graph-algorithm
1. 정의 및 특징
- 한 정점에서 나머지 정점들의 최단 거리를 구하는 알고리즘
- 음수 가중치 불가능(무한 루프)
- Min-Heap 방식(priorty queue로 구현)
- 가장 짧은 거리의 정점부터 연산
- 시간 복잡도 : O((V+E)logV)
- 각 노드마다 미방문 노드 중 출발점으로부터 현재까지 계산된 최단 거리를 가지는 노드를 찾는데 O(VlogV)의 시간이 필요
- 모든 노드(O(V))에 대해 Heap에서 최솟값을 검색 및 삭제(O(logV))
- 각 노드마다 이웃한 노드의 최단 거리를 갱신할 때 O(ElogV)의 시간이 필요
- 각 노드마다 모든 이웃을 확인하는 것은 모든 edge를 확인하는 것(O(E))과 같고, 매번 heap에서 최단 거리를 갱신(O(logV))
- 각 노드마다 미방문 노드 중 출발점으로부터 현재까지 계산된 최단 거리를 가지는 노드를 찾는데 O(VlogV)의 시간이 필요
2. 예제 코드
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int V, E, S;
vector< vector<pair<int, int>> > edge;
vector<int> dijkstra(int start) {
// 전부 -1로 초기화
vector<int> dist(V+1, -1);
priority_queue<pair<int, int>> pq; // first : -dist, second : vertex_pos
dist[start] = 0;
// Min-Heap 방식을 사용하기 위해 dist에 -1을 곱해준다.
pq.push(make_pair(-dist[start], start));
while (!pq.empty()) {
int from = pq.top().second;
int fromDist = -pq.top().first;
pq.pop();
/*
* 값이 커 pq 내부에서 우선순위가 계속 밀리고 밀린 애가 이제야 빠져 나오게 되었지만
* Dist가 더 작은 애가 먼저 빠져나와 진행되었기 때문에 여기서 걸러진다.
*/
if (fromDist > dist[from])
continue;
for (int i = 0; i < edge[from].size(); i++) {
int to = edge[from][i].first;
int toDist = fromDist + edge[from][i].second;
// 'dist[to] == -1'은 이전에 이미 node 'to'를 방문했었는지에 대한 여부를 판단하는 것
if \(dist\[to] == -1 \|| dist\[to] > toDist) {
// 최단 거리 갱신
dist[to] = toDist;
pq.push(make_pair(-toDist, to));
}
}
}
return dist;
}
int main() {
cin >> V >> E >> S;
edge.resize(V + 1);
for (int i = 0; i < E; i++) {
int from, to, dist
cin >> from >> to >> dist;
edge[from].push_back(make_pair(to, dist));
}
vector<int> dist = Dijkstra(S);
for (int i = 1; i <= V; i++)
cout << dist[i] << endl;
return 0;
}