[백준] 11657: 교환 - JAVA
https://www.acmicpc.net/problem/11657
풀이
도시마다 연결된 줄이 있고, 줄마다 가중치가 있다.
가중치에는 음수값도 있어서 1번도시에서 어떤 도시로 가는 과정에서 무한히 오래 전으로 돌릴 수 있으면 -1을 출력해야한다.
그렇지 않다면 2번~n번 도시까지 가는 가장 빠른 시간을 출력한다.
음수 가중치가 있기 때문에 벨만포드 알고리즘을 사용하는 문제였다.
벨만포드 알고리즘에서는 우선 ‘정점의 개수 - 1’만큼 루프를 돈다.
먼저 정점의 사이즈만큼 dist 배열을 만들어 출발지를 0으로 설정하고 나머지 값은 INF로 설정한다.
‘정점의 개수 - 1’만큼 루프를 돌면서 dist의 값이 INF가 아닌 정점에 대해 연결 된 정점까지 걸리는 cost를 최솟값으로 갱신한다.
‘정점의 개수 - 1’만큼 루프를 돌았다면, 한번 더 루프를 도는데, 이때 갱신되는 값이 있다면 문제에서 말하는 ‘무한히 오래 전으로 돌릴 수 있는’ 상황이 발생한 것이다.
메모리: 27188KB
시간: 304ms
언어: Java 11
코드
import java.io.*;
import java.util.*;
public class Main {
static class Node {
int v;
int cost;
public Node(int v, int cost) {
this.v = v;
this.cost = cost;
}
}
static int n, m;
static ArrayList<ArrayList<Node>> list;
static long[] dist;
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());
list = new ArrayList<>();
dist = new long[n + 1];
for (int i = 0; i < n + 1; i++) {
list.add(new ArrayList<>());
dist[i] = Integer.MAX_VALUE;
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
list.get(a).add(new Node(b, c));
}
boolean flag = bellmanFord();
StringBuilder sb = new StringBuilder();
if (flag) {
for (int i = 2; i <= n; i++) {
if (dist[i] == Integer.MAX_VALUE) {
sb.append(-1).append("\n");
} else {
sb.append(dist[i]).append("\n");
}
}
} else {
sb.append(-1).append("\n");
}
System.out.println(sb);
}
private static boolean bellmanFord() {
dist[1] = 0;
boolean flag = false;
for (int i = 0; i < n - 1; i++) {
flag = false;
for (int j = 1; j <= n; j++) {
for (Node node : list.get(j)) {
if (dist[j] == Integer.MAX_VALUE) {
break;
}
if (dist[node.v] > dist[j] + node.cost) {
dist[node.v] = dist[j] + node.cost;
flag = true;
}
}
}
if (!flag) {
break;
}
}
if (flag) {
for (int i = 1; i <= n; i++) {
for (Node node : list.get(i)) {
if (dist[i] == Integer.MAX_VALUE) {
break;
}
if (dist[node.v] > dist[i] + node.cost) {
return false;
}
}
}
}
return true;
}
}