• 문제 링크
11404번: 플로이드
첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가
www.acmicpc.net
• 풀이 과정
모든 노드간 최단 경로를 구하는 Floyd-Warshall 알고리즘을 활용한다.
2차원 배열에 자기 자신 노드로 이동하는 경우을 제외한 모든 최단 거리를 inf 값으로 지정하고,
이때 inf 값을 Integer.MAX_VALUE 로 지정 시 오버플로우가 발생할 수 있으므로
정점과 간선의 최대값의 곱에 1을 더한 수로 지정하였다.
이 후 간선의 정보를 입력받는데 같은 간선이 추가로 주어질 시 가중치의 최소값을 매번 갱신하여,
dist 배열에 각각의 간선의 최소 가중치값이 저장된다. (dist[src][dest] = Math.min(dist[src][dest], weight))
floydWarshall 함수에서 3중 for문으로 출발점(i), 경유점(k), 도착점(j) 를 구현하고,
아래의 코드를 통해 특정 경로의 출발점에서 도착점까지의 거리와
출발점에서 경유점을 거쳐 도착점까지의 거리를 비교하여 최단 거리를 갱신한다.
if (dist[i][j] > dist[i][k] + dist[k][j])
dist[i][j] = dist[i][k] + dist[k][j];
이렇게 모든 경로의 최단 거리가 저장된 dist 배열의 모든 원소를 정답으로써 출력하고,
만약 값의 변화가 없는 경로(dist[i][j] == inf) 는 존재하지 않는 경로이므로 0 을 출력한다.
• 풀이 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static int n;
static int[][] dist;
static int inf = 10000001;
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;
n = Integer.parseInt(br.readLine());
int m = Integer.parseInt(br.readLine());
dist = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j)
continue;
else
dist[i][j] = 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());
dist[src][dest] = Math.min(dist[src][dest], weight);
}
floydWarshall();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (dist[i][j] == inf)
bw.write("0 ");
else
bw.write(dist[i][j] + " ");
}
bw.write("\n");
}
bw.flush();
}
private static void floydWarshall() {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
if (i == k)
continue;
for (int j = 1; j <= n; j++) {
if (j == i || j == k)
continue;
if (dist[i][j] > dist[i][k] + dist[k][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
}
'Problem Solving > Baekjoon' 카테고리의 다른 글
[백준] 10844 쉬운 계단 수 - Dynamic Programming / Java (0) | 2022.08.23 |
---|---|
[백준] 1389 케빈 베이컨의 6단계 법칙 - Graph Theory / Java (0) | 2022.08.22 |
[백준] 1753 최단경로 - Graph Theory / Java (0) | 2022.08.20 |
[백준] 1916 최소비용 구하기 - Graph Theory / Java (0) | 2022.08.19 |
[백준] 1865 웜홀 - Graph Theory / Java (0) | 2022.08.18 |
댓글