본문 바로가기
백준/완전탐색

백준 10971. 외판원 순회 2

by 29살아저씨 2021. 8. 26.
반응형

🅰 백준 10971. 외판원 순회 2

 

10971번: 외판원 순회 2

첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j

www.acmicpc.net

✏️ 문제 풀이

  • 순열을 이용하여 모든 출발점에서 돌 수 있는 경우의 수를 뽑아낸 다음 비용을 계산해주었다.
  • 순열이 완성되면 비용행렬을 탐색하면서 가는 길이 없으면 비용들을 다 더했더라도 boolean변수를 이용하여 최소값으로 비교하지 못하게 하였다.

✏️ 소스코드

package bruteforce;

import java.util.*;
import java.io.*;
/*
 * 외판원 순회2 문제
 * 모든 노드들에 대해 순열을 하여 경우의 수를 파악한 후
 * 그 경우에 수에 따라 map에서 데이터를 더해준다.
 * 만약 연결되지 않은 노드 즉, map[x][y] == 0이라면 길이 없는 경우기 때문에 종료한다.*/
public class Main_실버2_10971_손은성 {

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		int input[] = new int[N];
		int min = Integer.MAX_VALUE;
		for (int i = 0; i < N; i++) {
			input[i] = i;
		}
		int map[][] = new int[N][N];
		for (int i = 0; i < N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			for (int j = 0; j < N; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}

		do {
			int sum = 0;
			boolean find = false;
			for (int i = 0; i < N-1; i++) {
				if(map[input[i]][input[i + 1]] == 0) find = true;   // break 해버리면 for문을 나가고, 밑에 N-1->0으로 가는 길이 있다면 답을 출력해버리는 문제가 있음 
																	// 그래서 boolean을 이용하여 if문안에서 0이면 수행을 못하게 함.
				sum += map[input[i]][input[i + 1]];
			}
			if(find||map[input[N-1]][input[0]] == 0)
				continue;
			sum+=map[input[N-1]][input[0]];
			min = Math.min(min, sum);
		} while (np(input));
		System.out.println(min);
	}

	//nextpermutation
	static boolean np(int input[]) {
		int N = input.length - 1;

		int i = N;
		while (i > 0 && input[i - 1] >= input[i])
			--i;
		if (i == 0)
			return false;

		int j = N;
		while (input[i - 1] >= input[j])
			--j;
		swap(input, i - 1, j);

		int k = N;
		while (i < k)
			swap(input, i++, k--);

		return true;
	}

	static void swap(int input[], int i, int j) {
		int temp = input[i];
		input[i] = input[j];
		input[j] = temp;
	}
}

 

✅ 후기

  • 다시 돌아보니 백트래킹으로 풀 수 있을 것 같은데 모든 경우의 수를 생각해서 풀었던 것 같다. 백트래킹으로 다시한번 풀어봐야겠다.
반응형

'백준 > 완전탐색' 카테고리의 다른 글

백준 1182. 부분수열의 합  (0) 2021.08.26
백준 6603. 로또  (0) 2021.08.26
백준 10819. 차이를 최대로  (0) 2021.08.26
백준 9095. 1, 2, 3 더하기  (0) 2021.08.26
백준 10974. 모든 순열  (0) 2021.08.26

댓글