๐ ์ต๋จ๊ฑฐ๋ฆฌ๋ฌธ์
๋ณดํต ์์๋ ธ๋๋ถํฐ ๋์ฐฉ๋ ธ๋๊น์ง์ ์ต๋จ๊ฒฝ๋ก๋ฅผ ๊ตฌํ๋ ํ์์ ๋ฌธ์ ์ด๋ค. MST์์ ์ ์ ์๋ฏ์ด ์ต๋จ๊ฒฝ๋ก๋ ์ ๋ ์ฌ์ดํด์ ํฌํจํ์ง ์๋๋ค. ์ต๋จ๊ฑฐ๋ฆฌ ๋ฌธ์ ๋ ๊ฐ์ค์น ์ ๋ฌด์ ๋ฐ๋ผ, ๊ฐ์ค์น๊ฐ ์์ ๊ฒฝ์ฐ์ ๊ฐ์ค์น์ ์์์ ๋ฐ๋ผ ์๋ง์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ค.
- ์์ ๊ฐ์ค์น๋ง ์์ ๋ : ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ(Dijkstra's Algorithm)
- ์์ ๊ฐ์ค์น๋ง ์์ ๋ : ๋ฒจ๋งํฌ๋ ์๊ณ ๋ฆฌ์ฆ(Bellman-Ford Algorithm)
- n ๋ n์ ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ๋ชจ๋ ๊ตฌํ๊ณ ์ถ์ ๋ : ํ๋ก์ด๋์์ฌ ์๊ณ ๋ฆฌ์ฆ(Floyd-Warshall Algorithm)
๐ ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ Dijkstra's Algorithm
์์ง์ ๊ฐ์ค์น๊ฐ ์์์ผ ๋ ์ฌ์ฉํ๋ค. ์์ ๊ฐ์ค์น๋ฅผ ๊ณ ๋ คํ์ง ์์ผ๋ฏ๋ก ๊ฐ์ค์น์ ํฉ์ด ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ์ข์ฐํ๋ค.
์์๋ ธ๋ ~ ์์๋ ธ๋ = 0 ์์ ์ด์ฉํด ๋ ธ๋๋ฅผ ํ ์นธ์ฉ ๋๋ ค๊ฐ๋ฉฐ ๋ชจ๋ ๋ ธ๋์ ๋ํด ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ๋ค. ์ด์ ๋จ๊ณ์์ ๊ตฌํ k-1 ๊น์ง์ ์ต๋จ๊ฑฐ๋ฆฌ ๊ฐ์ k-1 ~ k๋ฅผ ์ฐ๊ฒฐํ๋ ์์ง์ ๊ฐ์ค์น๋ฅผ ๋ํด์ฃผ๋ฉฐ, ๊ทธ ๊ฐ์ ๊ณ์ ๋น๊ตํด๋๊ฐ๋ ๋ฐฉ๋ฒ์ด๋ค.
์๊ฐ๋ณต์ก๋ : ๋งค๋ฒ ์ต๋จ๊ฒฝ๋ก๋ฅผ ์๊ฒ ๋๋ ๋ ธ๋๊ฐ ํ๋์ด๋ฏ๋ก ์ด ๊ณผ์ ์ ์ด ( V - 1 ) ๋ฒ ๋ฐ๋ณตํ๋ค. ๊ฐ ๋ ธ๋์ ๋ํด ์ต๋จ๊ฒฝ๋ก๋ฅผ ์ฐพ์ผ๋ ค๋ฉด ์ต๋ V ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ฏ๋ก O(V^2) ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค. ์ด๋ ๊ฐ ๋ ธ๋์ ๋ํด ์ต๋จ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ๋ ์ ํํ์์ด ์๋ Minheap(์ต์ํ)์ ์ฌ์ฉํ๋ฉด logV ์๊ฐ๋ง์ ์ต๋จ๊ฑฐ๋ฆฌ ๋ ธ๋๋ฅผ ์ฐพ์๋ผ ์ ์๋ค. ๊ฒฐ๊ตญ O(V logV)๊น์ง ์๊ฐ๋ณต์ก๋๋ฅผ ์ค์ผ ์ ์๋ค.
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
struct edge { int to, length; };
int dijkstra(const vector<vector<edge>>& graph, int source, int target) {
vector<int> min_distance(graph.size(), INT_MAX);
min_distance[source] = 0;
set<pair<int, int>> active_vertices;
active_vertices.insert(make_pair(0, source));
while (!active_vertices.empty()) {
int where = active_vertices.begin()->second;
if (where == target)
return min_distance[where];
active_vertices.erase(active_vertices.begin());
for (auto ed : graph[where]) {
if (min_distance[ed.to] > min_distance[where] + ed.length) {
active_vertices.erase(make_pair(min_distance[ed.to], ed.to));
min_distance[ed.to] = min_distance[where] + ed.length;
active_vertices.insert(make_pair(min_distance[ed.to], ed.to));
}
}
}
return INT_MAX;
}
์๋ํ์ ๊ต์๋์ ์์ฃผ ๊ฐ๊ฒฐํ ๋ค์ต์คํธ๋ผ ๊ตฌํ ์ฝ๋์
๋๋ค..
๐ ๋ฒจ๋งํฌ๋ ์๊ณ ๋ฆฌ์ฆ Bellman-Ford Algorithm
์์ง์ ๊ฐ์ค์น๊ฐ ์์์ผ ๋ ์ฌ์ฉํ๋ค. ์์ ๊ฐ์ค์น๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ๋ฅผ ๋ฐ๋ก ๊ณ ๋ คํด์ผ ํ๋ ์ด์ ๋ ์ต๋จ๊ฒฝ๋ก์์๋ ์ฌ์ดํด์ ํฌํจํ๋ฉด ์ ๋๊ธฐ ๋๋ฌธ์ด๋ค. MST(์ต์์ ์ฅํธ๋ฆฌ)๋ฅผ ๊ณต๋ถํ ๋ ๊นจ๋ฌ์ ๋ถ๋ถ์ด์ง๋ง, ์ต๋จ๊ฒฝ๋ก๋ ์ต์์์ง๋ฅผ ๊ฐ์ง๋ ๊ทธ๋ํ์์๋ ์ฌ์ดํด์ ํญ์ ํฌํจํ์ง ์๋๋ค. ๊ทธ๋ฐ๋ฐ ์์ ๊ฐ์ค์น๊ฐ ์๋ค๋ฉด? ์ฌ์ดํด์ ๋บ๋บ ๋๋ค๋ณด๋ฉด ๊ฐ์ค์น๊ฐ ์์ผ๋ก ๋ฐ์ฐํ ๊ฒ์ด๋ค(=๋๋ฆ ์ต์๊ฐ ๋์ด๊ฐ๋ ๊ฑฐ๊ฒ ์ง) ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ค์ต์คํธ๋ผ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๋น์ทํ ์์ด๋์ด์ง๋ง ์์ฃผ ์ฝ๊ฐ ๋ค๋ฅด๋ค. ๋ ธ๋ i ๋ถํฐ ๋ ธ๋ j ์ ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ค๊ณ ํ ๋, i ~ j ๋ฅผ ์ฐ๊ฒฐํ๋ ๋ฐ ์์ง k๊ฐ๋ฅผ ์ฐ๋ k + 1๊ฐ๋ฅผ ์ฐ๋๋ฅผ ๋น๊ตํ์ฌ ์์ง์ ๊ฐ์๊ฐ k + 1 ๊ฐ๋ก ๋ง๋๋ผ๋ ๊ฐ์ค์นํฉ์ด ๋ ์๋ค๋ฉด k + 1 ๊ฐ์ ์์ง๋ฅผ ๊ฒฝ์ ํ๋ ๊ธธ์ด ์ต๋จ๊ฒฝ๋ก๊ฐ ๋๋ ๊ฒ์ด๋ค. ๋ง์ด ์ด๋ ค์ด ๊ฑฐ ๊ฐ์ง๋ง ๊ฒฐ๊ตญ ์์ ์ฌ์ดํด์ด ์๊ธฐ์ง ์๋๋ก ํ๋ ๊ฒ์ด๋ค.
์๊ฐ๋ณต์ก๋ : ๋งค๋ฒ ๋ชจ๋ ์์ง๋ฅผ ์ ๊ฒํด์ผ ํ๋ฉฐ, ๋ง์ฐฌ๊ฐ์ง๋ก V - 1 ๋ฒ ๋ฐ๋ณตํด์ผ ํ๋ฏ๋ก O(V^2)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค.
๐ ํ๋ก์ด๋์์ ์๊ณ ๋ฆฌ์ฆ Floyd-Warshall Algorithm
1๊ฐ ๋๋ n๊ฐ์ ๋ ธ๋์ ๋ํด ์ต๋จ๊ฒฝ๋ก๋ฅผ ๊ตฌํ๋ ๊ฒ์ด ์๋๋ผ, n๊ฐ์ ๋ ธ๋์์ n๊ฐ์ ๋ ธ๋๊น์ง์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ์๊ณ ์ถ์ ๋ ํ๋ก์ด๋ ์์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ค. ๋ ธ๋ i ~ ๋ ธ๋ j ์ฌ์ด์ ๊ฐ๋ฅํ ๋ ธ๋ k ๋ฅผ ๋ชจ๋ ์ถ๊ฐํด ์ต๋จ๊ฑฐ๋ฆฌ๊ฐ ๋ฐ๋๋์ง๋ฅผ ํ์ธํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก, ์๊ฐ๋ณต์ก๋๊ฐ ๋ฌด๋ ค O(V^3)์ด๋ค^^
#include <iostream>
#include <climits>
using namespace std;
int graph[101][101] = { INT_MAX };
void FloydWarshall(int size) {
for (int k = 1; k < size + 1; k++) { // Vi ~ Vk ~ Vj
for (int i = 1; i < size + 1; i++) {
for (int j = 1; j < size + 1; j++) {
if (graph[i][k] && graph[k][j] && i != j) {
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]);
}
}
}
}
}