CS/Algorism

[백준] 17182. 우주 탐사선

olsohee 2024. 4. 11. 12:18

https://www.acmicpc.net/problem/17182

 

17182번: 우주 탐사선

우주 탐사선 ana호는 어떤 행성계를 탐사하기 위해 발사된다. 모든 행성을 탐사하는데 걸리는 최소 시간을 계산하려 한다. 입력으로는 ana호가 탐색할 행성의 개수와 ana호가 발사되는 행성의 위

www.acmicpc.net

  • 예를 들어 n이 3이고 시작점이 0일 때, (0 ➡️ 1로 가는 거리 + 0 ➡️ 2로 가는 거리)가 아닌 (0 ➡️ 1로 가는 거리 + 1 ➡️ 2로 가는 거리)가 더 짧을 수도 있다. 즉, 시작점에서 각 노드로 가는 거리만 최소로 갱신할 것이 아니라, 모든 노드에서 모든 노드로의 거리를 최소로 갱신하여 비교해야 한다. 따라서 플로이드 워셜을 사용해야 한다.
  • 플로이드 워셜을 통해 map 배열을 최단 거리로 갱신했으면 시작점에서 모든 노드를 탐색해야 한다. 그런데 이때 0 ➡️ 1 ➡️ 2로 가도 되고, 0 ➡️ 2 ➡️ 1로 가도 된다. 즉, 시작점에서 모든 노드를 탐색하는 순서는 여러가지가 있을 수 있으며, 모든 경우를 고려해야 한다. 따라서 dfs를 통해 모든 노드를 탐색하고, 모든 노드 탐색이 끝난 후에는 해당 경로에서 걸린 탐색시간을 answer에 갱신해주면 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int n;
    static int start;
    static int[][] map;
    static boolean[] visited;
    static int answer = Integer.MAX_VALUE;

    public static void main(String[] args) throws IOException {

        // 입력
        st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        start = Integer.parseInt(st.nextToken());
        map = new int[n][n];
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < n; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 1. 플로이드워셜로 map에 최단거리 갱신
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    map[i][j] = Math.min(map[i][j], map[i][k] + map[k][j]);
                }
            }
        }

        // 2. 시작점에서 dfs로 모든 노드 탐색하기(모든 경우의 수 탐색)
        visited = new boolean[n];
        dfs(0, start, 0);

        System.out.println(answer);
    }

    public static void dfs(int cnt, int start, int sum) {
        // 모든 노드를 탐색했으면 answer 값 갱신 후 끝내기
        if (cnt == n) {
            answer = Math.min(answer, sum);
            return;
        }

        for (int i = 0; i < n; i++) {
            if (!visited[i]) {
                visited[i] = true;
                dfs(cnt + 1, i, sum + map[start][i]);
                visited[i] = false; // 방문 처리 초기화
            }
        }
    }
}

'CS > Algorism' 카테고리의 다른 글

[백준] 16929. Two Dots  (0) 2024.04.12
[백준] 1261. 알고스팟  (0) 2024.04.11
[백준] 2531. 회전 초밥  (0) 2024.04.10
[백준] 2146. 다리 만들기  (0) 2024.04.10
소수인지 판단할 때 시간 복잡도 줄이기  (0) 2024.03.21