๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ์ ์ฃผ์ด์ง ๊ทธ๋ํ์ ์ ์ (Vertex)๊ณผ ๊ฐ์ (Edge)์ ์ฒ๋ฆฌํ์ฌ ๋ค์ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก BFS ์ DFS ๊ฐ ์์ต๋๋ค. ๊ทธ ์ค ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก BFS ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํฉ๋๋ค. ํ์ง๋ง BFS ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ํญ์ ์ผ์ ํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ ์ต์ ์ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก๋ ๋ค์ต์คํธ๋ผ , ๋ฒจ๋ง-ํฌ๋, ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ด ์์ต๋๋ค.
๊ฐ๊ฐ์ ์ฐจ์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ (Dijkstra's Algorithm)
์ฃผ์ด์ง ์์ ์ ์ ์์ ๋ค๋ฅธ ๋ชจ๋ ์ ์ ๊น์ง์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ฐ์ ์์ ํ๋ฅผ ์ฌ์ฉํด์ ๊ตฌํํฉ๋๋ค.
๊ฐ์ค์น๊ฐ ๋ชจ๋ ์์์ธ ๊ฒฝ์ฐ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
์๊ฐ ๋ณต์ก๋: O((V + E) log V) (์ฐ์ ์์ ํ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ)
์ ์ฉํ ์ ์๋ ์ฌ๋ก : ๋ค๋น๊ฒ์ด์ ์์คํ ์์ ์ต๋จ ๊ฒฝ๋ก ๊ณ์ฐ, ํจํท ์ ๋ฌ ๊ฒฝ๋ก ์ต์ ํ, ๊ฒ์์์ ์บ๋ฆญํฐ ์ด๋ ๊ฒฝ๋ก ๊ณ์ฐ
์๋๋ ๋ค์ต์คํธ๋ผ์ ํต์ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์ฐ์ ์์ํ์ distance ๋ฐฐ์ด์ ๋ฌดํ ๊ฐ์ผ๋ก ์ด๊ธฐํ ์์ผ๋๊ณ ์ด๊ฒ์ ๋ ธ๋์ ๋ ธ๋๊ฐ ์ฐ๊ฒฐ ๋๊ฑธ ๋ฐฉ๋ฌธํ๋ฉด์ ์ต๋จ ๊ฒฝ๋ก๋ก ์์ ์์ผ์ฃผ๋ ์๋ฆฌ์ ๋๋ค.
int start = 1;
int[] dist = new int[N + 1];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[start] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));
pq.offer(new int[]{start, 0});
while(!pq.isEmpty()){
int[] current = pq.poll();
int node = current[0];
int cost = current[1];
if(cost > dist[node]) continue;
for(Edge edge : graph.get(node)){
if(dist[edge.to] > dist[node] + edge.weight){
dist[edge.to] = dist[node] + edge.weight;
pq.offer(new int[]{edge.to, dist[edge.to]});
}
}
}
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ค๋ฉด ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
์ด๋ 5 → 2 ๊ฐ์ค์น๊ฐ 1์์ -2 ๋ก ๋ณํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์์ง๊น์ง ์ฌ์ ํ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ ์ ์์ต๋๋ค.
ํ์ง๋ง -2๋ณด๋ค ์ข ๋ ํฐ ์์์ธ -4๋ก ๋ฐ๋๋ค๋ฉด ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ๊ฒฐ๊ณผ๋ ์๋ ๊ฐ์ด ๋ฐ๋๋๋ค.
์ด๋ ๊ฒ ์์ ๊ฐ์ ์ ์ํ์ด ์๊ธฐ๊ฒ ๋๊ณ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ์์ ๋ฌดํ์ธ ๋ ธ๋๊ฐ ๋ฐ์ํ์ฌ ๊ทธ ๋ ธ๋๋ฅผ ํตํด์ ๋ค๋ฅธ ๋ ธ๋๋ฅผ ๊ฐ๊ฒ ๋์ ๋๋ -∞ + n ์ด๊ธฐ ๋๋ฌธ์ -∞ ๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์์ ์ํ ๊ณ ๋ฆฌ๊ฐ ์๊ธธ ์ ์์ผ๋ฏ๋ก ๋ค์ต์คํธ๋ผ๋ ์์ ๊ฐ์ ๊ฐ์ค์น๊ฐ ์์ ๋ ์ฌ์ฉํ์ง ๋ชปํฉ๋๋ค.
๋ํ ๋ฌธ์
https://www.acmicpc.net/problem/1753
๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ (Bellman-Ford Algorithm)
์ฃผ์ด์ง ์์ ์ ์ ์์ ๋ค๋ฅธ ๋ชจ๋ ์ ์ ๊น์ง์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ต๋๋ค.
๋ชจ๋ ๊ฐ์ ์ ๋ฐ๋ณต์ ์ผ๋ก ๊ฒ์ฌํ์ฌ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค. N-1๋ฒ์ ๋ฐ๋ณต์ ํตํด ๋ชจ๋ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅํ๊ณ , ์ถ๊ฐ์ ์ธ ๋ฐ๋ณต์ ํตํด ์์ ์ฌ์ดํด์ ์กด์ฌ๋ฅผ ํ์ธํฉ๋๋ค.(์ด๋ฌ๋ฏ๋ก ๋น์ฐํ ๋ค์ต์คํธ๋ผ์์ ๊ตฌํ ์ ์๋ ์ต์ ์ ํด๋ฅผ ๋ณด์ฅํฉ๋๋ค. ๋์ ๋ค์ต์คํธ๋ผ๋ณด๋ค ์๊ฐ ๋ณต์ก๋๊ฐ ํจ์ฌ ๋ง์ด ๊ฑธ๋ฆฌ๊ธฐ์ ๊ฐ์ค์น๊ฐ ์์๋ง ์กด์ฌํ๋ค๋ฉด ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํ๋ ๊ฒ์ด ํจ์ฌ ๊ฒฝ์ ์ ์ ๋๋ค.)
- ์์ ๊ฐ์ค์น๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
- ์ถ๊ฐ์ ์ธ ๋ฐ๋ณต์ ํตํด ์์ ์ฌ์ดํด์ ์กด์ฌ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค. N๋ฒ์งธ ๋ฐ๋ณต์์ ์ฌ์ ํ ๊ฑฐ๋ฆฌ๊ฐ ์ ๋ฐ์ดํธ๋๋ค๋ฉด ์์ ์ฌ์ดํด์ด ์กด์ฌํจ์ ์๋ฏธํฉ๋๋ค.
์๊ฐ ๋ณต์ก๋: O(V * E) ๋ชจ๋ ๊ฐ์ ์ N-1๋ฒ ๋ฐ๋ณตํ์ฌ ๊ฒ์ฌํ๊ธฐ ๋๋ฌธ์ ๋ ธ๋ ์์ ๊ฐ์ ์์ ๋น๋กํ๋ ์๊ฐ์ด ์์๋ฉ๋๋ค.
๋จ์ ๋ฆฌ์คํธ ๋๋ ๋ฐฐ์ด ์ฌ์ฉํ์ฌ ๊ตฌํํฉ๋๋ค.
์ ์ฉํ ์ ์๋ ์ฌ๋ก : ๊ธ์ต ๋ชจ๋ธ๋ง, ์์ ์ฌ์ดํด์ด ์๋ ๊ทธ๋ํ, ๊ธ์ต ์์คํ ์์ ๋ฌดํํ ์ด๋์ ์ป์ ์ ์๋ ์ฌ์ดํด ๊ฐ์ง
ํต์ฌ ์๊ณ ๋ฆฌ์ฆ์ ์๋์ ๊ฐ์ต๋๋ค.
int start = 1;
long[] dist = new long[N + 1];
Arrays.fill(dist, Long.MAX_VALUE);
dist[start] = 0;
// ๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ ์คํ
for(int i = 1; i < N; i++) {
for(Edge edge : edges){
if(dist[edge.from] != Long.MAX_VALUE && dist[edge.to] > dist[edge.from] + edge.weight){
dist[edge.to] = dist[edge.from] + edge.weight;
}
}
}
// ์์ ์ฌ์ดํด ๊ฐ์ง
boolean negativeCycle = false;
for(Edge edge : edges){
if(dist[edge.from] != Long.MAX_VALUE && dist[edge.to] > dist[edge.from] + edge.weight){
negativeCycle = true;
break;
}
}
๋ํ๋ฌธ์
https://www.acmicpc.net/problem/11657
ํ๋ก์ด๋-์์ ์๊ณ ๋ฆฌ์ฆ (Floyd-Warshall Algorithm)
๊ทธ๋ํ์ ๋ชจ๋ ์ ์ ์ ๊ฐ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ต๋๋ค.(๋จ์ผ ์์์ ์๋ ์ฃผ์)
๋ชจ๋ ์ ์ ์ ๊ฐ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ๋์ฌ์ฉ๋๊ณ , ์์ ๊ฐ์ค์น๋ฅผ ์ฒ๋ฆฌํ ์ ์์ง๋ง, ์์ ์ฌ์ดํด์ด ์๋ ๊ฒฝ์ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋์ ํ๋ก๊ทธ๋๋ฐ(DP)์ ์ด์ฉํด ์ค๊ฐ์ ๊ฒฝ์ ํ๋ ์ ์ ์ ์ ์ง์ ์ผ๋ก ๋๋ ค๊ฐ๋ฉฐ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
- ๊ทธ๋ํ์ ๋ชจ๋ ์ ์ ์ ๊ฐ์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ์ง์ ์ฐ๊ฒฐ๋ ๊ฐ์ ์ ๊ฑฐ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ , ์ฐ๊ฒฐ๋์ง ์์ ๊ฒฝ์ฐ ๋ฌดํ๋๋ก ์ค์ ํฉ๋๋ค.
- ๊ฐ ์ ์ ์ ์ค๊ฐ ์ ์ ์ผ๋ก ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ ์ ์ ๊ฐ์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์ ํฉ๋๋ค.
- ์ค๊ฐ ์ ์ ์ ํตํด ๋ ์งง์ ๊ฒฝ๋ก๊ฐ ๋ฐ๊ฒฌ๋๋ฉด ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
์๊ฐ ๋ณต์ก๋: O(V^3)
์ ์ฉํ ์ ์๋ ์ฌ๋ก : ๋ชจ๋ ์ ์ต๋จ ๊ฒฝ๋ก ๋ฌธ์ (๋ชจ๋ ์ ์ ์ ๊ฐ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์์ผ ํ๋ ๊ฒฝ์ฐ), ๋คํธ์ํฌ ๋ด ๋ชจ๋ ์ปดํจํฐ ๊ฐ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ๊ฒฝ์ฐ, ๊ตํต ์์คํ (๋์ ๊ฐ์ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๋ถ์ํ์ฌ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ๊ฒฝ์ฐ)
ํต์ฌ ์๊ณ ๋ฆฌ์ฆ์ ์๋์ ๊ฐ์ต๋๋ค.
int[][] dist = {
{0, 5, INF, 8},
{7, 0, 9, INF},
{2, INF, 0, 4},
{INF, INF, 3, 0}
};
// ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ
for (int k = 0; k < N; k++) { // ์ค๊ฐ์ ๊ฒฝ์ ํ๋ ๋
ธ๋
for (int i = 0; i < N; i++) { // ์์ ๋
ธ๋
for (int j = 0; j < N; j++) { // ๋์ฐฉ ๋
ธ๋
if (dist[i][j] > dist[i][k] + dist[k][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
๋ํ ๋ฌธ์
https://www.acmicpc.net/problem/11404
์์ฝ
์๊ณ ๋ฆฌ์ฆ | ๋ฐฉํฅ์ฑ ๊ทธ๋ํ | ๋ฌด๋ฐฉํฅ์ฑ ๊ทธ๋ํ | ์์ ๊ฐ์ค์น ๊ฐ์ | ์์ ์ฌ์ดํด ๊ฐ์ง |
๋ค์ต์คํธ๋ผ | ๊ฐ๋ฅ | ๊ฐ๋ฅ | ๋ถ๊ฐ๋ฅ | ๋ถ๊ฐ๋ฅ |
๋ฒจ๋ง-ํฌ๋ | ๊ฐ๋ฅ | ๊ฐ๋ฅ | ๊ฐ๋ฅ | ๊ฐ๋ฅ |
ํ๋ก์ด๋-์์ฌ | ๊ฐ๋ฅ | ๊ฐ๋ฅ | ๊ฐ๋ฅ(์์ ์ฌ์ดํด ์์ ์) | ๋ถ๊ฐ๋ฅ |
๋๊ธ