17182번 - 우주 탐사선
2025-01-01
#JAVA#백준
문제 풀이 시간 : 1시간
문제 풀이:
처음에는 그냥 플로이드로 모든 경로의 최단 거리를 구하고
각 위치에서 가지 않은 행성 중 최단 거리인 행성을 골라서 가는 방식으로 문제를 풀었다.
플로이드 함수
public static void update() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(i==j)
continue;
for (int k = 0; k < n; k++) {
arr[j][k] = Math.min(arr[j][k], arr[j][i] + arr[i][k]);
}
}
}
}
최단 거리 계산
Queue<Integer> q = new LinkedList<>();
visited[k] = true;
q.add(k);
int sum = 0;
while (!q.isEmpty()) {
int a = q.poll();
int min = Integer.MAX_VALUE;
int idx = a;
for (int i = 0; i < n; i++) { //현재 행성에서 갈 수 있는 모든 행성 탐색
if (visited[i]||a==i) { //방문했거나 현재 행성과 같다면 패스
continue;
}
if (min > arr[a][i]) { //이동 시간이 더 짧다면 교체
min = arr[a][i];
idx = i;
}
}
if (idx != a) { //현재 행성과 저장된 행성이 같다면 모든 행성을 방문했다는 뜻
sum += min;
visited[idx] = true;
q.add(idx);
}
}
근데 이건 아주 잘못된 접근이었다.
제대로된 풀이를 하려면 시작지점에서부터 모든 경우를 계산하면 되는 것이다.
실제로 모든 경우의 수를 다 해보더라도 행성의 개수가 10개이므로 크게 부담되지 않는다.
그래서 위의 코드에서 최단 거리 계산 코드를 아래와 같은 코드로 바꿔주면 된다.
public static void calc(int cnt, int a, int sum) { //행성 방문 개수, 현재 행성, 거리 합계
if (ans < sum) { //이미 최단값보다 크다면 할필요 없음
return;
}
if (cnt >= n) { //모든 행성을 방문했다면 최단값 업데이트
ans = sum;
return;
}
for (int i = 0; i < n; i++) {
if (visited[i] || a == i) {
continue;
}
visited[i] = true;
calc(cnt + 1, i, sum + arr[a][i]); //재귀
visited[i] = false;
}
}
전체 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static int n,k;
public static int ans = Integer.MAX_VALUE;
public static int[][] arr;
public static boolean[] visited;
public static void calc(int cnt, int a, int sum) {
if (ans < sum) {
return;
}
if (cnt >= n) {
ans = sum;
return;
}
for (int i = 0; i < n; i++) {
if (visited[i] || a == i) {
continue;
}
visited[i] = true;
calc(cnt + 1, i, sum + arr[a][i]);
visited[i] = false;
}
}
public static void update() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(i==j)
continue;
for (int k = 0; k < n; k++) {
arr[j][k] = Math.min(arr[j][k], arr[j][i] + arr[i][k]);
}
}
}
}
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());
k = Integer.parseInt(st.nextToken());
arr = new int[n][n];
visited = new boolean[n];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
update();
visited[k] = true;
calc(1, k, 0);
System.out.println(ans);
}
}