[JAVA/백준] SW 역량 테스트 준비-기초 | 브루트 포스: 외판원 순회 2

👀 문제

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

👊 도전

1. 설계

  1. DFS를 이용하여 모든 경우에 수를 체크한다.

2. 구현 (성공 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.Scanner;

/**
 * @author HEESOO
 *
 */
public class Main {
	static int n;
	static int[][] w;
	static boolean[] visit;
	static int min=Integer.MAX_VALUE;
	public static void dfs(int start, int depart, int depth, int sum) {
		if(depth==n && start==depart) {
			sum+=w[depart][start];
			min=Math.min(min, sum);
			return;
		}
		for(int j=0;j<n;j++) {
			if(w[depart][j]==0||visit[j]) continue;
			visit[j]=true;
			dfs(start, j, depth+1, sum+w[depart][j]);
			visit[j]=false;
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan = new Scanner(System.in);
		n=scan.nextInt();
		w=new int[n][n];
		visit=new boolean[n];
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				w[i][j]=scan.nextInt();
		
		for(int i=0;i<n;i++)
			dfs(i,i,0,0);
		
		System.out.println(min);
	}
}

3. 결과

실행결과 🤟 성공 🤟
dfs의 return조건에 다시 원래의 도시로 돌아온 경우를 추가하지 않아 실패했다.

4. 설명

  1. DFS를 이용하여 모든 경우를 구한다
    • 시작 도시(start)별로 모든 도시들을 방문해야하므로 DFS를 이용해야한다.
    • 시작 도시가 주어지지 않았기 때문에 main에서 for문을 통해 모두 체크한다.
    • dfs의 파라미터 start는 처음 시작 도시, depart는 출발지, depth는 방문한 도시 수, sum은 지금까지의 비용이다.
    • for문의 j를 이용하여 현재 depart에서 방문할 수 있는 도시들을 체크한다. visit[j]가 false라면 방문하지 않은 곳이므로 true로 바꾼 후 dfs를 통해 방문, 방문이 끝난 후에는 다음 사용을 위해 다시 false로 초기화한다.
    • dfs는 n개의 도시를 모두 방문했고, 시작 도시로 도착했을 경우에만 min의 값을 갱신 및 종료한다. 지금보니 sum에 더하는 코드는 무조건 0이므로 필요가 없다.

👏 해결 완료!

참고