1. ๋ฒจ๋งํฌ๋(Bellman-Ford) ์๊ณ ๋ฆฌ์ฆ์ด๋?
- ํ ๋ ธ๋์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๊น์ง์ ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ + ์์ ์ฌ์ดํด ์กด์ฌ ์ฌ๋ถ๋ฅผ ์ ์ ์์
- ๋ค์ต์คํธ๋ผ์๋ ๋ฌ๋ฆฌ ๊ฐ์ค์น์ ์์๊ฐ ์์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ
- ์๊ฐ๋ณต์ก๋: O(NE) (N:๋ ธ๋์ ์, E:์ฃ์ง์ ์)
- ๋ค์๊ณผ ๊ฐ์ ๊ทธ๋ํ๊ฐ ์๋ค๊ณ ๊ฐ์
- ๋ค์ต์คํธ๋ผ๋ก ๋ ธ๋ 1์์ ๋ชจ๋ ๋ ธ๋๋ก์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ฉด
- 1 -> 2 = 1
- 1 -> 2 ->3 = 2
- 1-> 2 ->3 ->4 = 4 ๊ฐ ๋๊ณ
- ๋ ธ๋ 2๋ ์ด๋ฏธ ๋ฐฉ๋ฌธํ๊ธฐ ๋๋ฌธ์ 4 ->2 ๊ฒฝ๋ก๋ ๊ณ ๋ คํ์ง ์์
- ๊ฒฐ๊ณผ์ ์ผ๋ก 1 -> 2์ ์ต๋จ๊ฒฝ๋ก๋ 1์ด ๋จ
- ํ์ง๋ง ์ค์ 1 -> 2์ ์ต๋จ๊ฒฝ๋ก๋ -∞ ์
- ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฒจ๋งํฌ๋ ์๊ณ ๋ฆฌ์ฆ ํ์
2. ์๊ณ ๋ฆฌ์ฆ ๋์ ์๋ฆฌ
- ์์ ์ ์ ์ ์ ํํ๋ค.
- ๋ชจ๋ ๊ฐ์ ๋ค์ ํ์ํ๋ฉด์, ์์ ์ ์ ์์ ๋ค๋ฅธ ์ ์ ๊น์ง์ ๊ฑฐ๋ฆฌ๊ฐ INF๊ฐ ์๋๋ผ๋ฉด ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์ ํ๋ค. ์ด ๊ณผ์ ์ (์ ์ ์ ์ -1)๋ฒ๋งํผ ์งํํ๋ค.
- ๋ง์ง๋ง์ผ๋ก 2๋ฒ์ ์ํํ๋ค.
2๋ฒ ๊ณผ์ ์์ (์ ์ ์ ์-1)๋ฒ ๋งํผ ์งํํ๋ ์ด์ ๋ V๊ฐ์ ์ ์ ๊ณผ E๊ฐ์ ๊ฐ์ ์ด ์๋ ๊ฐ์ค ๊ทธ๋ํ์์ ์ ์ A์์ ์ ์ B๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ ์ต๋ V-1๊ฐ์ ์ ์ ์ ์ง๋๊ธฐ ๋๋ฌธ์ด๋ค.
V-1๊ฐ ์ด์์ ์ ์ ์ ๋ฐฉ๋ฌธํ๋ ๊ฒ์ ๊ฒฐ๊ตญ ์ค๋ณต ๋ฐฉ๋ฌธ์ ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ต๋จ ๊ฒฝ๋ก๊ฐ ์ฑ๋ฆฝ๋ ์ ์๋ค.
๋ํ, 3๋ฒ ๊ณผ์ ์์ ๋ง์ง๋ง์ผ๋ก 2๋ฒ ๊ณผ์ ์ ํ ๋ฒ ๋ ์ํํ๋ ์ด์ ๋ ์์ ์ฌ์ดํด ์ ๋ฌด๋ฅผ ํ๋จํ๊ธฐ ์ํด์์ด๋ค. ๋ง์ฝ V ๊ฐ์ ์ ์ ์ ์ง๋ฌ๋๋ฐ ์ต๋จ ๊ฒฝ๋ก๊ฐ ๊ฐฑ์ ์ด ๋๋ค๋ฉด ์์ ์ฌ์ดํด์ด ๋ฐ์ํ ๊ฒ์ด๋ฉฐ ๋น์ฉ์ด ๋ฌดํํ๊ฒ ๊ฐฑ์ ์ด ๋๊ธฐ ๋๋ฌธ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ ์ ์๋ค.
๊ทธ๋ฆผ๊ณผ ํจ๊ป ์์๋ณด์.
1. ์ด๊ธฐํ
์ถ๋ฐ์ง(์์ ๋ ธ๋)๋ฅผ ์ ์ธํ ๋ชจ๋ ๋ ธ๋๋ก์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฌดํ๋๋ก ์ด๊ธฐํํ๋ค. ์ถ๋ฐ์ง์ ๊ฑฐ๋ฆฌ๋ 0์ด๋ค.
2. ์ต๋จ๊ฑฐ๋ฆฌ ๊ณ์ฐ
V-1๋ฒ ๋์ ๋ชจ๋ ์ฃ์ง๋ฅผ ํ์ธํ๋ค.
ํ์ฌ ์ฃ์ง์ ๋์ฐฉ์ง์ ์ ์ ์ฅ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ณด๋ค ํ์ฌ ์ฃ์ง๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ + ํ์ฌ ์ฃ์ง์ ๊ฑฐ๋ฆฌ๊ฐ ์งง์ ๊ฒฝ์ฐ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์ ํ๋ค.
for(i=1; i<V; i++) // V-1๋ฒ
for(Edge now : EdgeList) // ๋ชจ๋ ์ฃ์ง์ ๋ํด
if(distance[now.end] > dist[now.start] + now.cost)
distance[now.end] = dist[now.start] + now.cost
์ด๋, ์ฃ์ง์ ์ถ๋ฐ์ง๊ฐ ๋ฌดํ๋์ธ ๊ฒฝ์ฐ์ ๊ฐฑ์ ์ด ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ฒซ ๋ฒ์งธ ํ์์์๋ ์์ ์ ์ ๊ณผ ์ด์ด์ง ์ฃ์ง๋ง ๊ฐฑ์ ์ด ๋ฐ์ํ๋ค.
์ฆ, ์ฒซ ๋ฒ์งธ ํ์์์ ์ฃ์ง๊ฐ ์ต๋ ํ๋ ํฌํจ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๊ตฌํด์ง๋ค.
๋ ๋ฒ์งธ์์๋ ๊ฑฐ๊ธฐ์ ํ๋ ๋ ๋์๊ฐ ์ ์๊ฒ ๋๋ฏ๋ก ์ต๋ ๋ ๊ฐ์ ์ฃ์ง๊ฐ ํฌํจ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๊ตฌํด์ง๋ค.
๋ฐ๋ผ์ i๋ฒ์งธ ํ์์ i๊ฐ์ ์ฃ์ง๊ฐ ํฌํจ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๊ตฌํด์ง๊ณ , ๊ฒฝ๋ก์๋ ์ฌ์ดํด์ด ์๊ธฐ๋ฉด ์ ๋๊ธฐ ๋๋ฌธ์ ์ต๋จ ๊ฑฐ๋ฆฌ ํ์์ V-1๋ฒ์ผ๋ก ๋๋๋ค.
3. V๋ฒ์งธ ํ์ - ํ์ธ ๊ณผ์
V-1๋ฒ์์ ์ต๋จ ๊ฑฐ๋ฆฌ ํ์์ด ๋๋๊ธฐ ๋๋ฌธ์ ๋์ด์ ํ์์ ์งํํด๋ ๊ฐฑ์ ์ด ๋ฐ์ํด์๋ ์ ๋๋ค.
V๋ฒ์งธ์ ๊ฐฑ์ ์ด ๋ฐ์ํ๋ค → ์์ ์ฌ์ดํด์ด ์กด์ฌํ๋ค.
for(Edge now : EdgeList)
if(distance[now.end] > dist[now.start] + now.cost)
return false // ์์ ์ฌ์ดํด ์กด์ฌ
return true
์์๋ฌธ์ ํ์ด
https://www.acmicpc.net/problem/11657
๋ฌธ์
N๊ฐ์ ๋์๊ฐ ์๋ค. ๊ทธ๋ฆฌ๊ณ ํ ๋์์์ ์ถ๋ฐํ์ฌ ๋ค๋ฅธ ๋์์ ๋์ฐฉํ๋ ๋ฒ์ค๊ฐ M๊ฐ ์๋ค. ๊ฐ ๋ฒ์ค๋ A, B, C๋ก ๋ํ๋ผ ์ ์๋๋ฐ, A๋ ์์๋์, B๋ ๋์ฐฉ๋์, C๋ ๋ฒ์ค๋ฅผ ํ๊ณ ์ด๋ํ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด๋ค. ์๊ฐ C๊ฐ ์์๊ฐ ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. C = 0์ธ ๊ฒฝ์ฐ๋ ์๊ฐ ์ด๋์ ํ๋ ๊ฒฝ์ฐ, C < 0์ธ ๊ฒฝ์ฐ๋ ํ์๋จธ์ ์ผ๋ก ์๊ฐ์ ๋๋์๊ฐ๋ ๊ฒฝ์ฐ์ด๋ค.
1๋ฒ ๋์์์ ์ถ๋ฐํด์ ๋๋จธ์ง ๋์๋ก ๊ฐ๋ ๊ฐ์ฅ ๋น ๋ฅธ ์๊ฐ์ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์์ค.
์ ๋ ฅ
์ฒซ์งธ ์ค์ ๋์์ ๊ฐ์ N (1 ≤ N ≤ 500), ๋ฒ์ค ๋ ธ์ ์ ๊ฐ์ M (1 ≤ M ≤ 6,000)์ด ์ฃผ์ด์ง๋ค. ๋์งธ ์ค๋ถํฐ M๊ฐ์ ์ค์๋ ๋ฒ์ค ๋ ธ์ ์ ์ ๋ณด A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)๊ฐ ์ฃผ์ด์ง๋ค.
์ถ๋ ฅ
๋ง์ฝ 1๋ฒ ๋์์์ ์ถ๋ฐํด ์ด๋ค ๋์๋ก ๊ฐ๋ ๊ณผ์ ์์ ์๊ฐ์ ๋ฌดํํ ์ค๋ ์ ์ผ๋ก ๋๋๋ฆด ์ ์๋ค๋ฉด ์ฒซ์งธ ์ค์ -1์ ์ถ๋ ฅํ๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด N-1๊ฐ ์ค์ ๊ฑธ์ณ ๊ฐ ์ค์ 1๋ฒ ๋์์์ ์ถ๋ฐํด 2๋ฒ ๋์, 3๋ฒ ๋์, ..., N๋ฒ ๋์๋ก ๊ฐ๋ ๊ฐ์ฅ ๋น ๋ฅธ ์๊ฐ์ ์์๋๋ก ์ถ๋ ฅํ๋ค. ๋ง์ฝ ํด๋น ๋์๋ก ๊ฐ๋ ๊ฒฝ๋ก๊ฐ ์๋ค๋ฉด ๋์ -1์ ์ถ๋ ฅํ๋ค.
public class Main {
static int N;
static int M;
static List<Node> graph;
static int INF = Integer.MAX_VALUE;
static long[] dist;
static class Node {
int start;
int end;
int time;
public Node(int start, int end, int cost) {
this.start = start;
this.end = end;
this.time = cost;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
graph = new ArrayList<>();
dist = new long[N+1];
Arrays.fill(dist, INF);
dist[1] = 0; // ์ถ๋ฐ์ง๋ 0์ผ๋ก
for(int i = 1; i <= M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
int time = Integer.parseInt(st.nextToken());
graph.add(new Node(start, end, time));
}
if(bellmanFord()) System.out.println(-1);
else {
StringBuilder sb = new StringBuilder();
for(int i = 2; i<=N; i++) {
if(dist[i]==INF) sb.append(-1);
else sb.append(dist[i]);
sb.append("\n");
}
System.out.println(sb);
}
}
static boolean bellmanFord() {
/* 1. ์ต๋จ๊ฑฐ๋ฆฌ ๊ณ์ฐ */
for(int i = 1; i <= M; i++) {
for(Node node : graph) {
if(dist[node.start] != INF && dist[node.end] > dist[node.start] + node.time) { // ๊ฐฑ์
if(i == M) return true; // 2. ์ฌ์ดํด ๋ฐ์ ์ฌ๋ถ ์ฒดํฌ
dist[node.end] = dist[node.start] + node.time;
}
}
}
return false;
}
}
๐์ฐธ๊ณ ์ฌ์ดํธ