[백준]#17182 우주 탐사선

SeungBird·2020년 12월 5일
0

⌨알고리즘(백준)

목록 보기
244/401

문제

우주 탐사선 ana호는 어떤 행성계를 탐사하기 위해 발사된다. 모든 행성을 탐사하는데 걸리는 최소 시간을 계산하려 한다. 입력으로는 ana호가 탐색할 행성의 개수와 ana호가 발사되는 행성의 위치와 ana호가 행성 간 이동을 하는데 걸리는 시간이 2차원 행렬로 주어진다. 행성의 위치는 0부터 시작하여 0은 행렬에서 0번째 인덱스에 해당하는 행성을 의미한다. 2차원 행렬에서 i, j 번 요소는 i 번째 행성에서 j 번째 행성에 도달하는데 걸리는 시간을 나타낸다. i와 j가 같을 때는 항상 0이 주어진다. 모든 행성을 탐사하는데 걸리는 최소 시간을 계산하여라.

탐사 후 다시 시작 행성으로 돌아올 필요는 없으며 이미 방문한 행성도 중복해서 갈 수 있다.

입력

첫 번째 줄에는 행성의 개수 N과 ana호가 발사되는 행성의 위치 K가 주어진다. (2 ≤ N ≤ 10, 0 ≤ K < N)

다음 N 줄에 걸쳐 각 행성 간 이동 시간 Tij 가 N 개 씩 띄어쓰기로 구분되어 주어진다. (0 ≤ Tij ≤ 1000)

출력

모든 행성을 탐사하기 위한 최소 시간을 출력한다.

예제 입력 1

3 0
0 30 1
1 0 29
28 1 0

예제 출력 1

2

예제 입력 2

4 1
0 83 38 7
15 0 30 83
67 99 0 44
14 46 81 0

예제 출력 2

74

풀이

이 문제는 Floyd-Warshall(플로이드 와샬), DFS(깊이 우선 탐색) 알고리즘을 이용해서 풀 수 있었다. 한번 지나간 정거장을 다시 갈 수 있기 때문에 플로이드-와샬 알고리즘을 이용해서 전체 최단 거리를 구하고 DFS 알고리즘을 이용해서 각 정거장의 순서를 정해서 그 거리 중 최단거리를 구했다.

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    static int[][] map;
    static int N;
    static int ans = Integer.MAX_VALUE;

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");
        N = Integer.parseInt(input[0]);
        int start = Integer.parseInt(input[1]);
        map = new int[N][N];

        for(int i=0; i<N; i++) {
            input = br.readLine().split(" ");
            for(int j=0; j<N; j++)
                map[i][j] = Integer.parseInt(input[j]);
        }
        
        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]);     //플로이드 와샬 알고리즘으로 최소 거리 구함
                }
            }
        }

        boolean[] visited = new boolean[N];
        visited[start] = true;
        dfs(visited, start, 0, 0);

        System.out.println(ans);
    }

    public static void dfs(boolean[] visited, int temp, int sum, int depth) {
        if(depth==N-1) {
            ans = Math.min(ans, sum);     //최단 거리 구하기
            return ;
        }

        for(int i=0; i<N; i++) {
            if(!visited[i]) {
                visited[i] = true;
                dfs(visited, i, sum+map[temp][i], depth+1);   //안지나간 정거장 지나가기
                visited[i] = false;
            }
        }
    }
}
profile
👶🏻Jr. Programmer

0개의 댓글