• 문제 링크
11657번: 타임머신
첫째 줄에 도시의 개수 N (1 ≤ N ≤ 500), 버스 노선의 개수 M (1 ≤ M ≤ 6,000)이 주어진다. 둘째 줄부터 M개의 줄에는 버스 노선의 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)가 주어진다.
www.acmicpc.net
• 풀이 과정
한 노드(1번 도시)에서 다른 모든 노드(나머지 도시)까지의 최단 거리(최단 시간)를 구하고
타임머신이라는 간선의 가중치가 음수인 경우가 존재하므로 Bellman-Ford 알고리즘을 활용한다.
각 노드의 최단 거리를 dist 배열에 무한대 값(inf) 으로 초기화하고,
각 간선의 출발, 도착점, 가중치의 정보를 Edge 객체로 저장한다.
1번 노드를 출발 노드로 나머지 노드들의 최단 거리를 갱신하고
음의 사이클 존재 여부를 반환하는 bellmanFord 함수를 실행한다.
노드의 개수 n 회만큼 모든 간선을 탐색하며
간선의 출발점까지의 최단 거리가 inf 가 아니고,(dist[s] != inf)
도착점의 누적된 최단 거리가, 출발점 최단 거리와 현재 간선의 가중치의 합보다 클 경우,(dist[d] > dist[s] + w)
도착점의 최단 거리를 작은 최단 거리값으로 갱신한다.(dist[d] = dist[s] + w)
이때 n 번째 순회에서 값의 갱신이 이루어진다면 음의 사이클이 존재하므로 true 를 반환, -1 을 출력한다.
false 를 반환하여 음의 사이클이 존재하지 않는다면
2 ~ n 의 모든 노드까지의 최단 거리를 정답으로써 출력하고
만약 값의 갱신이 없었다면 해당 노드로 가는 경로가 없으므로 -1 을 출력한다.
• 풀이 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static int n, m;
static long[] dist;
static List<Edge> list;
static int inf = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
dist = new long[n + 1];
list = new ArrayList<>();
for (int i = 1; i <= n; i++)
dist[i] = inf;
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int src = Integer.parseInt(st.nextToken());
int dest = Integer.parseInt(st.nextToken());
int weight = Integer.parseInt(st.nextToken());
list.add(new Edge(src, dest, weight));
}
if (bellmanFord(1))
bw.write(-1 + "\n");
else {
for (int i = 2; i <= n; i++) {
if (dist[i] == inf)
bw.write(-1 + "\n");
else
bw.write(dist[i] + "\n");
}
}
bw.flush();
}
private static boolean bellmanFord(int root) {
dist[root] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < m; j++) {
int s = list.get(j).src;
int d = list.get(j).dest;
int w = list.get(j).weight;
if (dist[s] != inf && dist[d] > dist[s] + w) {
dist[d] = dist[s] + w;
if (i == n)
return true;
}
}
}
return false;
}
private static class Edge {
int src, dest, weight;
public Edge(int src, int dest, int weight) {
this.src = src;
this.dest = dest;
this.weight = weight;
}
}
}
'Problem Solving > Baekjoon' 카테고리의 다른 글
[백준] 1916 최소비용 구하기 - Graph Theory / Java (0) | 2022.08.19 |
---|---|
[백준] 1865 웜홀 - Graph Theory / Java (0) | 2022.08.18 |
[백준] 1197 최소 스패닝 트리 - Graph Theory / Java (0) | 2022.08.16 |
[백준] 1922 네트워크 연결 - Graph Theory / Java (0) | 2022.08.15 |
[백준] 2056 작업 - Graph Theory / Java (0) | 2022.08.14 |
댓글