BOJ
[백준 10971번] 외판원 순회 2 (java)
lotus lee
2021. 3. 18. 11:04

10971번: 외판원 순회 2
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j
www.acmicpc.net
어느 한 도시에서 출발하여 모든 도시를 거친 후, 처음으로 돌아오는 문제이다.
여기서 알아야 할 사실은 어느 도시에서 출발하든 가장 적게 드는 비용은 동일하다는 것이다.


따라서 아무나 한 곳을 시작도시로 정해서 dfs를 사용하여 시작한 곳으로 돌아오면 된다.
모든 도시를 한 번씩만 방문해야하므로 visited 배열을 이용하여 방문 여부를 표시한다.
그런데 문제를 풀면서 한가지 헷갈렸던 점이 있다.
처음 시작한 도시는 이미 처음에 방문처리가 될 것이다. 각 도시마다 방문 여부를 확인한 뒤 방문하지 않은 도시만 방문하는데, 마지막에 다시 처음 도시로 돌아올 때는 해당 도시가 이미 방문처리 되어있기 때문에 이에 대한 처리를 별도로 해줘야 한다.
그래서 시작도시를 갈 수 있는 방법은 방문 여부와 관계없이 방문한 도시 개수를 카운트하여, 모든 도시를 다 방문했을 때만 시작도시를 다시 갈 수 있도록 했다.
if (n == start && cnt == N) { // 인접한 도시가 시작도시이고, 모든 도시를 다 방문한 상태인 경우
cost += w[now][n];
dfs(start, n, cnt + 1, cost);
}
시작도시가 아닌 나머지 도시는 아직 방문하지 않았을 때만(visited[n] = false) 방문하도록 했다.
소스코드 :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
public class n10971 { | |
static int N; | |
static int[][] w; | |
static boolean[] visited; | |
static int min = Integer.MAX_VALUE; | |
public static void main(String[] args) throws Exception { | |
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | |
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); | |
N = Integer.parseInt(br.readLine()); | |
w = new int[N + 1][N + 1]; | |
visited = new boolean[N + 1]; | |
for (int i = 1; i <= N; i++) { | |
String[] sarr = br.readLine().split(" "); | |
for (int j = 1; j <= N; j++) { | |
w[i][j] = Integer.parseInt(sarr[j - 1]); | |
} | |
} | |
visited[1] = true; | |
dfs(1, 1, 1, 0); | |
bw.write(min + "\n"); | |
bw.flush(); | |
} | |
public static void dfs(int start, int now, int cnt, int cost) { | |
if (now == start && cost > 0) { | |
min = Math.min(min, cost); | |
return; | |
} | |
for (int n = 1; n <= N; n++) { | |
if (w[now][n] > 0) { | |
if (n == start && cnt == N) { | |
cost += w[now][n]; | |
dfs(start, n, cnt + 1, cost); | |
} | |
else if (!visited[n]) { | |
visited[n] = true; | |
cost += w[now][n]; | |
dfs(start, n, cnt + 1, cost); | |
cost -= w[now][n]; | |
visited[n] = false; | |
} | |
} | |
} | |
} | |
} |