다익스트라(dijkstra) 알고리즘과 벨만-포드(bellman-ford) 알고리즘이 있다.
다익스트라 알고리즘은 노드의 가중치가 양수일 때만 사용 가능한 알고리즘이다 (시간복잡도 : )
반면, 벨만-포드 알고리즘은 노드의 가중치가 음수일 때도 사용 가능한 알고리즘이다. (시간복잡도 : )
노드간의 가중치가 모두 양수라면 다익스트라를 선택하면 되고, 음수가 존재한다면 벨만-포드를 선택하면 되겠다.
모든 노드로 나올 수 있는 노드 쌍에 대한 최단경로를 구하는 알고리즘은 플로이드 워셜(Floyd-Warshall) 알고리즘이다.
구현이 간단하며, 음의 가중치에서도 사용 가능하다.
시간복잡도가 인 단점이 있다.
알고리즘이 있다. 이는 다익스트라(Dijkstra) 알고리즘을 확장한 것이다.
다익스트라 알고리즘이 한 노드에서 다른 한 노드까지의 최단경로를 구하는 것을 포함하므로 알고리즘 대신 다익스트라 알고리즘이 사용되는 경우가 많다.
pop()
하면 인접 노드의 최단경로 노드를 구할 수 있다.우선 순위 큐를 사용한 구현은 아래와 같다.
백준 문제 1916번이 전형적인 다익스트라를 구현해 푸는 문제이므로 해당 문제로 다익스트라 알고리즘을 구현하였다.
백준 1916
#include <iostream>
#include <queue>
#define N 1001
#define INF 100000000
using namespace std;
vector<pair<int, int>> graph[N];
priority_queue<pair<int, int>> pq;
int dist[N];
int n, m;
void init_dist(int n) {
for(int i = 1; i <= n; i++) dist[i] = INF;
}
void dijkstra(int start) {
pq.push({0, start}); // 첫 노드 pq에 삽입 (거리는 0)
dist[start] = 0;
while(!pq.empty()) {
int cur_dist = -pq.top().first;
int cur_node = pq.top().second;
pq.pop();
if(dist[cur_node] < cur_dist) continue;
for(int i = 0; i < graph[cur_node].size(); i++) {
int nxt_node = graph[cur_node][i].first;
int nxt_dist = dist[cur_node] + graph[cur_node][i].second;
if(dist[nxt_node] > nxt_dist) {
dist[nxt_node] = nxt_dist;
pq.push({-nxt_dist, nxt_node});
}
}
}
}
int main() {
cin >> n >> m;
int from, to, cost;
for(int i = 0; i < m; i++) {
cin >> from >> to >> cost;
graph[from].push_back({to, cost});
}
int start, dest;
cin >> start >> dest;
init_dist(n);
dijkstra(start);
cout << dist[dest];
return 0;
}
pq
에 값을 {거리, 노드} 순으로 삽입을 진행한다. 이때 우선순위 큐는 최대 힙이 아닌 최소 힙이므로 {-거리, 노드}로 값을 푸쉬해야 가장 작은 거리부터 순서대로 pop()
할 수 있다.