
다익스트라 알고리즘
- 하나의 정점에서 다른 모든 정점으로 가는 최단 경로를 알 수 있다.
- 음의 간선이 존재하는 경우 사용할 수 없다.
- 다익스트라 알고리즘은 일종의 다이나믹 알고리즘이라고 할 수 있으며 그 이유는 작은 최단 경로의 합이 전체적인 최단경로가 되기 때문이고 따라서 이전에 구한 최단 거리 정보를 그대로 사용한다.
다익스트라 알고리즘의 시간복잡도
- 가장 작은 간선의 값을 가진 노드를 찾을 때 선형 탐색을 이용한다면 O(N2)
- 그 이유는 가장 작은 노드를 찾을 때 for문이 쓰여 이 부분이 선형 탐색이라면 O(N) 그 위에 시작 노드와 끝 노드를 뺀 나머지 노드를 모두 탐색해야하므로 for문에 쓰이기 때문에 이중 for문O(N)이 되기 때문이다.
- 힙을 이용한다면 루트 노트에 가장 작은 값이 항상 오기 때문에 선형 탐색을 할 필요가 없어서 시간 복잡도가 O(NlogN)이다.
- priority_queue를 사용하여 구현한다.
다익스트라 알고리즘 예시

- d 배열은 출발 노드부터의 각 노드까지의 최단 거리 저장 배열
- v 배열은 방문 처리 배열로 F는 미방분 T는 방문
- 출발 노드가 1번노드인 경우 흐름

다익스트라 알고리즘 구현(선형탐색)
#include <iostream>
using namespace std;
int number = 6;
int INF = 987654321;
int a[6][6] = {
{0, 2, 1, 4, INF, 5},
{2, 0, INF, INF, 4, INF},
{1, INF, 0, 2, 4, 5},
{4, INF, 2, 0, INF, INF},
{INF, 4, 4, INF, 0, 3},
{5, INF, 5, INF, 3, 0}
};
bool v[6] = { 0 };
int d[6] = { 0 };
int getSmallIndex() {
int min = INF;
int index = 0;
for (int i = 0; i < number; i++) {
if (d[i] < min && !v[i]) {
min = d[i];
index = i;
}
}
return index;
}
void dijkstra(int start) {
for (int i = 0; i < number; i++) {
d[i] = a[start][i];
}
v[start] = true;
for (int i = 0; i < number - 2; i++) {
int current = getSmallIndex();
v[current] = true;
for (int j = 0; j < number; j++) {
if (!v[j]) {
d[j] = min(d[current] + a[current][j], d[j]);
}
}
}
}
int main() {
dijkstra(0);
for (int i = 0; i < number; i++) {
cout << d[i] << " ";
}
return 0;
}
다익스트라 알고리즘 구현(우선순위 큐)
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int number = 6;
int INF = 987654321;
vector<pair<int, int>> a[7];
int d[7];
void dijkstra(int start) {
d[start] = 0;
priority_queue<pair<int, int>> pq;
pq.push(make_pair(start, 0));
while (!pq.empty()) {
int current = pq.top().first;
int distance = -pq.top().second;
pq.pop();
if (d[current] < distance) continue;
for (int i = 0; i < a[current].size(); i++) {
int next = a[current][i].first;
int nextDistance = distance + a[current][i].second;
if (nextDistance < d[next]) {
d[next] = nextDistance;
pq.push(make_pair(next, -nextDistance));
}
}
}
}
int main() {
for (int i = 1; i <= number; i++) {
d[i] = INF;
}
a[1].push_back(make_pair(2, 2));
a[1].push_back(make_pair(3, 1));
a[1].push_back(make_pair(4, 4));
a[1].push_back(make_pair(6, 5));
a[2].push_back(make_pair(1, 2));
a[2].push_back(make_pair(5, 4));
a[3].push_back(make_pair(1, 1));
a[3].push_back(make_pair(4, 2));
a[3].push_back(make_pair(5, 4));
a[3].push_back(make_pair(6, 5));
a[4].push_back(make_pair(1, 4));
a[4].push_back(make_pair(3, 2));
a[5].push_back(make_pair(2, 4));
a[5].push_back(make_pair(3, 4));
a[5].push_back(make_pair(6, 3));
a[6].push_back(make_pair(1, 5));
a[6].push_back(make_pair(3, 5));
a[6].push_back(make_pair(5, 3));
dijkstra(1);
for (int i = 1; i <= number; i++) {
cout << d[i] << " ";
}
return 0;
}