문제 풀이 날짜: 2023.10.11
포스트 작성일: 2023.10.16
* 학습 목적으로 작성하는 글입니다. 풀이가 정석적이지 못할 수도 있습니다.
문제 출처
백준 온라인 저지 17182번: 우주 탐사선 (골드3)
키워드
플로이드-워샬, DFS
풀이 접근법
- 입력 그래프가 인접 행렬로 주어지며, 모든 행성을 탐사하기 위한 최소 시간이 필요하므로 플로이드-워샬로 풀이한다.
- 그런데 여기서 플로이드 워샬로 구해진 결과물은 단순히 각 점으로 가는 최소 시간(최단 경로)일 뿐이다. 우리가 구하고 싶은 것은 시작점부터 모든 정점을 지나는 최소 시간이다.
- 따라서 0부터 모든 정점을 지나는 경로는 DFS(그래프 탐색)로 구해준다. (N은 최대 10)
- 시작점 K는 문제에서 주어진다. 중복 경우를 제거하기 위해 시작점을 visit하고 depth 1부터 시작한다.
- Why? : 어떤 시작점 A에서 출발해서 B, C, D를 방문한다고 가정할 때, A부터 방문해야 하는 것은 이미 자명한 사실임.
- ⇒ 시작점을 제외한 (N-1)! 가지 경우의 수만 구하면 된다.
- 또, A에서 출발하여 B에 도착하는 경우를 찾고싶을 때 A-B-(C-D) 라는 경우까지 구해버리면 유의미한 경우의 수가 아님.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private static int N;
private static int K;
private static final int INF = 9_999_999;
private static boolean[] visited;
private static int[][] D;
private static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] temp = br.readLine().split(" ");
N = Integer.parseInt(temp[0]);
K = Integer.parseInt(temp[1]);
visited = new boolean[N];
D = new int[N][N];
StringTokenizer st;
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 0; j < N; j++) {
D[i][j] = Integer.parseInt(st.nextToken());
}
}
//플로이드 워샬
for(int k = 0; k < N; k++) { //경
for(int i = 0; i < N; i++) { //출
for(int j = 0; j < N; j++) { //도
D[i][j] = Math.min(D[i][k] + D[k][j], D[i][j]);
}
}
}
visited[K] = true; //시작점을 체크하고 진입한다.
DFS(1, K, 0); //주의: depth가 1부터 시작
System.out.println(min);
}
private static void DFS(int depth, int start, int dist) {
if(depth == N) {
min = Math.min(dist, min);
return;
}
for(int i = 0; i < N; i++) {
if(i == start) { continue; }
if(!visited[i]) {
visited[i] = true;
DFS(depth + 1, i, dist + D[start][i]);
visited[i] = false;
}
}
}
}
참고한 링크
https://bleron.tistory.com/215
https://dlwnsdud205.tistory.com/253
'Study > Problem Solving' 카테고리의 다른 글
[백준 / Java] 24230번: 트리 색칠하기 (골드5) (0) | 2023.10.16 |
---|---|
[SWEA / Java] 14510번: 나무 높이 (D2) (0) | 2023.10.16 |
[백준 / Java] 17144번: 미세먼지 안녕! (골드4) (0) | 2023.10.16 |
[SWEA / Java] 5656번: [모의 SW 역량테스트] 벽돌 깨기 (0) | 2023.10.16 |
[백준 / Java] 2042번 : 구간 합 구하기 (골드1) (0) | 2023.10.12 |