C++로 구현
#include <stdio.h>
#include <algorithm>
using namespace std;
#define INF 10000000
#define N 5
int weight[N][N] = {{0, 10, 5, INF, INF},
{INF, 0, 2, 1, INF},
{INF, 3, 0, 9, 2},
{INF, INF, INF, 0, 4},
{7, INF, INF, 6, 0}};
bool visited[N] = {false};
int dist[N] = {0};
int min_node = 0;
// 방문하지 않은 노드들 중,
// 최단 거리가 가장 짧은 노드 인덱스 반환
int get_smallest_node()
{
int min = INF;
int node = -1;
for (int i = 0; i < N; i++)
{
if (visited[i] == true)
continue;
if (min > dist[i])
{
min = dist[i];
node = i;
}
}
return node;
}
void dijkstra(int start)
{
// 방문한 노드에 시작 정점 저장
visited[start] = true;
// distance 배열 초기화
for (int i = 0; i < N; i++)
{
dist[i] = weight[start][i];
}
while (1)
{
// 1. 최소 노드 추가
min_node = get_smallest_node();
if (min_node == -1)
{
break;
}
visited[min_node] = true;
// 2. 1로 인해 단축되는 경로 있는지 확인하여 distance 값 수정
for (int i = 0; i < N; i++)
{
if (visited[i] == true || weight[min_node][i] == INF)
{
continue;
}
dist[i] = min(dist[i], dist[min_node] + weight[min_node][i]);
}
}
}
int main(void)
{
dijkstra(0);
for (int i = 0; i < N; i++)
printf("dist[%d]: %d\n", i, dist[i]);
return 0;
}
위의 방법은 정점 개수만큼 for문을 두 번 써서 순회 → 시간복잡도
우선순위 큐(=힙)을 써서 최단거리가 가장 짧은 노드를 탐색할 경우 → 최악의 경우 시간 복잡도
C++로 구현
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define INF 10000000
#define N 5
// graph[0].first = 정점 0에서 first로 감
// graph[0].second = 정점 0에서 first로 갈 때 드는 비용
vector<pair<int,int>> graph[N];
// 최단거리 배열
int shortest_distance[N];
void dijkstra(int start)
{
int distance = 0, min_node_index = 0, new_cost = 0;
priority_queue<pair<int,int>> pq; // {거리, 정점 인덱스}, 우선순위 큐는 기본이 내림차순임에 유의
pq.push({0, start}); // 시작 정점으로 가기 위한 최단 경로는 0으로 설정
shortest_distance[start] = 0;
while (!pq.empty())
{
// 최단 거리 노드(min_node_index) 찾기
min_node_index = pq.top().second;
distance = -pq.top().first;
pq.pop();
if (shortest_distance[min_node_index] < distance) // 이미 최단경로를 체크한 경우
continue;
for (int i = 0; i < graph[min_node_index].size(); i++)
{
int modifying_node = graph[min_node_index][i].first;
int second_cost = graph[min_node_index][i].second;
new_cost = distance + second_cost;
if (new_cost < shortest_distance[modifying_node])
{
shortest_distance[modifying_node] = new_cost;
pq.push({-new_cost, modifying_node});
}
}
}
}
int main(void)
{
// 간선 정보 입력.
// 아래 줄 내용: 정점 0에서 정점 0으로 갈 때 드는 비용은 0이다
graph[0].push_back({0, 0});
graph[0].push_back({1, 10});
graph[0].push_back({2, 5});
graph[1].push_back({1, 0});
graph[1].push_back({2, 2});
graph[1].push_back({3, 1});
graph[2].push_back({1, 3});
graph[2].push_back({2, 0});
graph[2].push_back({3, 9});
graph[2].push_back({4, 2});
graph[3].push_back({3, 0});
graph[3].push_back({4, 4});
graph[4].push_back({0, 7});
graph[4].push_back({3, 6});
graph[4].push_back({4, 0});
// 최단거리 배열을 모두 INF로 초기화
fill(shortest_distance, shortest_distance + N, INF);
dijkstra(0);
for (int i = 0; i < N; i++)
{
printf("shortest_distance[%d]: %d\n", i, shortest_distance[i]);
}
return 0;
}