[Algo] 최단거리 알고리즘
대표적인 최단 거리 알고리즘
최단거리 알고리즘은 대표적으로 3가지가 있는데, 각각의 알고리즘마다 시간복잡도, 사용가능 상황 등의 차이점이 조금씩 있다.
다익스트라 (Dijkstra algorithm)
최단거리 알고리즘은 대표적으로 3가지가 있는데, 각각의 알고리즘마다 시간복잡도, 사용가능 상황 등의 차이점이 조금씩 있다.
제한사항 : 모든 가중치가 음이 아닌 값을 가지고 있어야 함.
결과 : 한 정점에서 다른 모든 정점의 최단거리를 알 수 있음.
시간복잡도 : O(E * logV)
음의 가중치를 포함하지 못하는 이유
벨만 포드와의 차이점
다익스트라는 현재까지 방문한 정점들 중에서 거리가 최소인 정점을 고르고 나면, 더 이상 이 정점에 대해서 업데이트를 해주지 않는다. 그렇기 때문에 간선에 음의 가중치가 포함되어 있다면, 전에 골랐던 최소 정점을 업데이트 해줘야 하는 상황이 발생하므로 다익스트라는 음의 가중치를 포함할 수가 없다.
벨만 포드 알고리즘과의 큰 차이점 간선에 음의 가중치를 포함시킬 수 없다는 점이다.
그림으로 보기

코드로 보기
struct Node {
int next;
int weight;
};
struct compare {
bool operator()(const Node& n1, const Node& n2) {
return n1.weight > n2.weight;
}
};
void dijkstra() {
vector<vector<Node>> graph = make_graph(edges, V);
priority_queue<Node, vector<Node>, compare> min_node;
vector<int> distance(V, INF);
vector<bool> check(V);
distance[K] = 0;
min_node.push(Node(K, 0));
while (!min_node.empty()) {
Node top = min_node.top();
min_node.pop();
if (check[top.next]) continue;
check[top.next] = true;
for (auto i : graph[top.next]) {
if (check[i.next]) continue;
if (distance[i.next] > top.weight + i.weight) {
distance[i.next] = top.weight + i.weight;
min_node.push(Node(i.next, top.weight + i.weight));
}
}
}
for (auto d : distance) {
if (d == INF) {
cout << "INF\n";
}
else {
cout << d << "\n";
}
}
}
벨만 포드 (Bellman Ford algorithm)
제한사항 : graph에 음의 길이를 가지는 cycle이 없어야 함.
결과 : 한 정점에서 다른 모든 정점의 최단거리를 알 수 있음.
시간복잡도 : O(VE)
다익스트라와의 차이점
- 음의 간선이 있어도 사용할 수 있다.
시간복잡도가O(VE)로 다익스트라보다 느리다.
그림으로 보기

코드로 보기
#include <iostream>
#include <climits>
#include <vector>
#include <queue>
#define INF 987654321
using namespace std;
struct Edge {
int u;
int v;
int cost;
};
struct Node {
int next;
int weight;
Node(int _next, int _weight) { next = _next; weight = _weight; }
};
vector<vector<Node>> make_graph(vector<Edge>& edges, int N) {
vector<vector<Node>> graph(N);
for (auto edge : edges) {
graph[edge.u].push_back( Node(edge.v, edge.cost) );
}
return graph;
}
void bellman_ford(vector<Edge>& edges, int N) {
vector<vector<Node>> graph = make_graph(edges, N);
vector<int> distance(N, INF);
queue<int> q;
q.push(0);
distance[0] = 0;
// 음의 cycle을 가지는지 판단하기 위해 N - 1번이 아닌 N번 돌음.
for (int iter = 0; iter < N; iter++) {
if (q.empty()) {
break;
}
int size = q.size();
vector<bool> node_distance_update(N);
for (int i = 0; i < size; i++) {
int front = q.front();
q.pop();
for (auto node : graph[front]) {
if (distance[node.next] > distance[front] + node.weight) {
distance[node.next] = distance[front] + node.weight;
if (!node_distance_update[node.next]) {
node_distance_update[node.next] = true;
q.push(node.next);
}
}
}
}
}
if (!q.empty()) {
cout << "-1";
}
else {
for (int i = 1; i < N; i++) {
int curr = distance[i];
if (curr == INF) {
cout << "-1\n";
}
else {
cout << curr << "\n";
}
}
}
}
int main() {
int N, M;
cin >> N >> M;
vector<Edge> edges(M);
for (auto& i : edges) {
cin >> i.u >> i.v >> i.cost;
i.u--; i.v--;
}
bellman_ford(edges, N);
return 0;
}
플로이드 와샬 (Floyd Warshall)
제한사항 : grpah에 음의 cycle이 없어야 함.
결과 : 모든 정점에서 다른 모든 정점의 최단거리를 알 수 있음.
시간복잡도 : O(N3)
그림으로 보기
작성 중
코드로 보기
작성 중
Author And Source
이 문제에 관하여([Algo] 최단거리 알고리즘), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@alirz-pixel/Algo-최단거리-알고리즘저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)