Article Image
Article Image
read
문제
우주 탐사선 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;
}
}
}
}