๐ ๋ฒจ๋งโํฌ๋(BellmanโFord) ์๊ณ ๋ฆฌ์ฆ
๋จ์ผ ์์์ ์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ (one - to - all)
๋ค์ต์คํธ๋ผ(Dijkstra)์ ๋ฌ๋ฆฌ ์์ ๊ฐ์ค์น ๊ฐ์ ์ด ์์ด๋ ๋์ ๊ฐ๋ฅ
์๊ฐ ๋ณต์ก๋: O(VยทE) (์ ์ V, ๊ฐ์ E)
์์ ์ ์ s์์ ๊ฑฐ๋ฆฌ๋ฅผ ์ด๊ธฐํ
dist[s] = 0, ๋๋จธ์ง ์ ์ ์ INF
๋ชจ๋ ๊ฐ์ ์ ๋ํด V-1๋ฒ ๋ฐ๋ณตํ์ฌ ์ํ(Relaxation)
์ํ: ๋ ์งง์ ๊ฒฝ๋ก๋ฅผ ๋ฐ๊ฒฌํ๋ฉด ๊ฑฐ๋ฆฌ ๊ฐฑ์
if (dist[u] + w < dist[v]) dist[v] = dist[u] + w;
ํ ๋ฒ ๋ ๋ชจ๋ ๊ฐ์ ์ ๊ฒ์ฌํด์ ๊ฐฑ์ ์ด ๊ฐ๋ฅํ๋ค๋ฉด
โ ์์ ์ฌ์ดํด ์กด์ฌ
k๋ฒ์งธ ๋ฐ๋ณต ํ dist[v]๋ ์์์ ์์ v๊น์ง ๊ฐ์ ์ต๋ k๊ฐ๋ฅผ ์ฌ์ฉํ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ์๋ฏธ
๋ฐ๋ผ์ V-1๋ฒ ๋ฐ๋ณตํ๋ฉด ๋ชจ๋ ๋จ์ ๊ฒฝ๋ก๋ฅผ ๊ณ ๋ คํ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๋ณด์ฅ
์ต๋จ ๊ฒฝ๋ก๋ ๊ฐ์ ์ด ์ต๋ V-1๊ฐ
๊ทธ ์ดํ์๋ ๊ฐฑ์ ์ด ๋ฐ์ํ๋ค๋ฉด, ์ฌ์ดํด์ ํฌํจํ๋ ๊ฒฝ๋ก๊ฐ ๋ ์งง์์ก๋ค๋ ๋ป
์ด๋ ๊ณง ์์ ์ฌ์ดํด ์กด์ฌ๋ฅผ ์๋ฏธ
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringBuilder sb = new StringBuilder();
static StringTokenizer st;
static class Edge {
int u;
int v;
int cost;
public Edge(int u, int v, int cost) {
this.u = u;
this.v = v;
this.cost = cost;
}
}
static int N, M;
static long[] dis;
static List<Edge> graph = new ArrayList<>();
public static void main(String[] args) throws IOException {
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
graph.add(new Edge(u, v, cost));
}
if(!bellmanFord(1)){
System.out.println(-1);
System.exit(0);
}
for (int i = 2; i <= N; i++) {
sb.append(dis[i] == Long.MAX_VALUE ? -1 : dis[i]).append("\n");
}
System.out.println(sb.toString());
}
private static boolean bellmanFord(int start) {
dis = new long[N + 1];
Arrays.fill(dis, Long.MAX_VALUE);
dis[start] = 0;
for (int i = 1; i <= N - 1; i++) {
for (Edge edge : graph) {
if (dis[edge.u] != Long.MAX_VALUE && dis[edge.v] > dis[edge.u] + edge.cost) {
dis[edge.v] = dis[edge.u] + edge.cost;
}
}
}
for (Edge edge : graph) {
if (dis[edge.u] != Long.MAX_VALUE && dis[edge.v] > dis[edge.u] + edge.cost) {
return false;
}
}
return true;
}
}
๋ฒจ๋งโํฌ๋ ์๊ณ ๋ฆฌ์ฆ ์ต์ ํ ๋ฒ์
ํต์ฌ ์์ด๋์ด: ๊ฑฐ๋ฆฌ ๋ฐฐ์ด์ด ์ค์ ๋ก ๊ฐฑ์ ๋ ์ ์ ๋ง ๋ค์ ํ์
์ผ๋ฐ์ ์ผ๋ก ๋ค์ต์คํธ๋ผ๋ณด๋ค ๋๋ฆฌ์ง๋ง, ์์ ๊ฐ์ ์ด ์๋ ๊ฒฝ์ฐ์ ์์ฃผ ํ์ฉ๋จ
์์ ์ ์ s์์ dist[s]=0์ผ๋ก ์ด๊ธฐํํ๊ณ ํ(queue)์ ์ฝ์
ํ์์ ์ ์ ์ ๊บผ๋ด ๊ทธ ์ ์ ์ ์ฐ๊ฒฐ๋ ๊ฐ์ ์ ํ์ธ
๋ ์งง์ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ผ๋ฉด dist[v]๋ฅผ ๊ฐฑ์ ํ๊ณ , ์ ์ v๋ฅผ ํ์ ๋ฃ์
๋จ, v๊ฐ ์ด๋ฏธ ํ์ ์์ผ๋ฉด ์ค๋ณต ์ฝ์ ํ์ง ์์
ํ๊ฐ ๋น ๋๊น์ง ๋ฐ๋ณต
์ฆ, ๋ถํ์ํ ์ํ๋ฅผ ์ค์ด๊ณ , ํ์ํ ์ ์ ๋ง ๋ค์ ํ์ธํ๋ ๋ฐฉ์.
์ต์ : O(VยทE) (๋ฒจ๋งโํฌ๋์ ๋์ผ)
ํ๊ท : O(E)์ ๊ฐ๊น์ด ์ฑ๋ฅ์ ๋ณด์ด๋ ๊ฒฝ์ฐ๋ ๋ง์
๋ฐ๋ผ์ ์ค์ ์์๋ ํ๊ท ์ ์ผ๋ก ๋งค์ฐ ๋น ๋ฅด์ง๋ง, ์ต์ ์ฑ๋ฅ ๋ณด์ฅ์ด ์๋ ์๊ณ ๋ฆฌ์ฆ
์ด๋ค ์ ์ ์ด V๋ฒ ์ด์ ํ์ ๋ค์ด๊ฐ๋ฉด ์์ ์ฌ์ดํด์ด ์กด์ฌํ๋ค๊ณ ํ๋ณํ ์ ์๋ค.
(์ต๋จ ๊ฒฝ๋ก๊ฐ ๋ฌดํํ ์ค์ด๋๋ ํ์)
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringBuilder sb = new StringBuilder();
static StringTokenizer st;
static class Edge {
int v;
int cost;
public Edge(int v, int cost) {
this.v = v;
this.cost = cost;
}
}
static int N, M;
static long[] dis;
static boolean[] inQueue;
static int[] count;
static List<Edge>[] graph;
public static void main(String[] args) throws IOException {
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
graph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
graph[u].add(new Edge(v, cost));
}
if (!SPFA(1)) {
System.out.println(-1);
System.exit(0);
}
for (int i = 2; i <= N; i++) {
sb.append(dis[i] == Long.MAX_VALUE ? -1 : dis[i]).append("\n");
}
System.out.println(sb.toString());
}
private static boolean SPFA(int start) {
dis = new long[N + 1];
Arrays.fill(dis, Long.MAX_VALUE);
inQueue = new boolean[N + 1];
count = new int[N + 1];
Queue<Integer> q = new LinkedList<>();
dis[start] = 0;
q.add(start);
inQueue[start] = true;
count[start]++;
while (!q.isEmpty()) {
int u = q.poll();
inQueue[u] = false;
for (Edge e : graph[u]) {
if (dis[u] != Long.MAX_VALUE && dis[e.v] > dis[u] + e.cost) {
dis[e.v] = dis[u] + e.cost;
if (!inQueue[e.v]) {
q.add(e.v);
inQueue[e.v] = true;
count[e.v]++;
if (count[e.v] >= N) {
return false; // ์์ ์ฌ์ดํด ์กด์ฌ
}
}
}
}
}
return true;
}
}
๋ฐฑ์ค 11657 ํ์๋จธ์
https://www.acmicpc.net/problem/11657