BOJ 10971 : 외판원 순회 2 - https://www.acmicpc.net/problem/10971
Traveling Salesman problem(TSP), 외판원 순회의 기본적인 문제이다.
DFS로 풀이하면 되는 문제! 모든 지점을 방문하는 최소 비용을 구한다. 방문 여부를 체크해서 한번 방문했던 도시는 다시 방문할 수 없다
라는 조건을 만족시켜야 한다.
도시 간의 비용이 0일 경우 갈 수 있는 루트가 없는 것이기 때문에 dfs의 조건을 A 도시를 방문하지 않았으며 A 도시로 가는 루트가 존재할 경우 - if (!visited[i] && map[now][i] != 0)
으로 정의했다.
모든 도시를 방문했고, 마지막 도시에서 처음 도시로 가는 루트가 존재하면 cost를 비교하여 최솟값을 알아낸다.
출발 지점을 문제에서 지정해주지 않았기 때문에 모든 도시를 출발지로 한번씩 dfs()를 호출한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n;
static boolean[] visited;
static int[][] map;
static long result_min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
StringTokenizer st;
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());
}
}
for(int i=0; i<n; i++) {
visited = new boolean[n];
visited[i] = true;
dfs(i, i, 0);
}
System.out.println(result_min);
}
public static void dfs(int start, int now, long cost){
if (allVisited()) {
if(map[now][start]!=0){
result_min = Math.min(result_min, cost+map[now][0]);
}
return;
}
for(int i=1; i<n; i++){
if (!visited[i] && map[now][i] != 0) {
visited[i] = true;
dfs(start, i, cost + map[now][i]);
visited[i] = false;
}
}
}
public static boolean allVisited() {
for (int i = 0; i < n; i++) {
if (!visited[i]) {
return false;
}
}
return true;
}
}
✔ 알고리즘 분류 - 브루트포스 알고리즘, 백트래킹, 외판원 순회 문제
✔ 난이도 - ⚪ Silver 2
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
StringTokenizer st;
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());
}
}
visited = new boolean[n];
visited[0] = true;
dfs(0, 0); // dfs 한번만
System.out.println(result_min);
}
public static void dfs(int now, long cost){
if (allVisited()) {
if(map[now][0]!=0){ // 첫번째 도시로 가는 길이 있을 경우
result_min = Math.min(result_min, cost+map[now][0]);
}
return;
}
for(int i=1; i<n; i++){
if (!visited[i] && map[now][i] != 0) {
visited[i] = true;
dfs(i, cost + map[now][i]);
visited[i] = false;
}
}
}
딱히 없음
덕분에 좋은 내용 잘 보고 갑니다
감사합니다.