문제링크 : https://www.acmicpc.net/problem/10971
10971번: 외판원 순회 2
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j
www.acmicpc.net
접근 과정 :
- 한 도시에서 출발하여 모든 도시를 방문한 뒤, 출발 도시로 돌아왔을 때의 비용이 가장 적은 것을 출력하는 문제.
- 방문체크를 하면서 완전탐색을 하는 방법을 생각
- 도시의 수가 최대 10개이기에, 비용을 저장한 배열을 그냥 탐색하면서 다음 경로를 추적.
- 방문체크는 비트를 이용하여 판단
- 비용을 누적해가면서 경로를 추적하다가, 만약 이미 갱신된 최저비용보다 현재 비용이 더 많다면 그 경로는 중단
소스 코드 및 결과 :
package BOJ;
/*
외판원 순회 2
*/
import java.io.*;
import java.util.*;
public class BOJ10971 {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
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());
}
}
minCost = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
travel(i, i, 0, 0);
}
System.out.println(minCost);
}
static int N;
static int[][] map;
static int minCost;
static void travel(int start, int now, int visit, int cost) {
if(cost > minCost){
return;
}
if (visit == (1 << N)-1 && start == now) {
minCost = Math.min(minCost, cost);
return;
}
for (int i = 0; i < N; i++) {
if (map[now][i] == 0 || (visit | (1 << i)) == visit) {
continue;
}
travel(start, i, visit | (1 << i), cost + map[now][i]);
}
return;
}
}
P.S
조건이 도시에 한번만 방문해야한다는 것 뿐이었고, 도시의 개수가 크지 않아서 크게 어려운 문제는 아니었다.
TSP로 불리는 중요한 유형이라는데... 비슷한 다른 문제도 풀어봐야겠다.
+ (최저 비용 > 현재 비용) 부분 체크안하니까, 많은 시간이 소모되더라.
'Algorithm' 카테고리의 다른 글
[백준 Silver 1] 1309 동물원 - Java (0) | 2021.12.23 |
---|---|
[백준 Gold 1] 2098 외판원 순회 - Java (0) | 2021.12.22 |
[백준 Gold 2] 14657 준오는 최종인재야!! - Java (0) | 2021.12.21 |
[백준 Gold 3] 13701 중복 제거 - Java (0) | 2021.12.21 |
[백준 Silver 1] 2961 도영이가 만든 맛있는 음식 - Java (0) | 2021.12.21 |