본문 바로가기

알고리즘

[Algorithm] 외판원 순회

시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초128 MB109712271132626.185%

문제

외판원 순회 문제는 영어로 Traveling Salesman problem (TSP) 라고 불리는 문제로 computer science 분야에서 가장 중요하게 취급되는 문제 중 하나이다. 여러 가지 변종 문제가 있으나, 여기서는 가장 일반적인 형태의 문제를 살펴보자.

1번부터 N번까지 번호가 매겨져 있는 도시들이 있고, 도시들 사이에는 길이 있다. (길이 없을 수도 있다) 이제 한 외판원이 어느 한 도시에서 출발해 N개의 도시를 모두 거쳐 다시 원래의 도시로 돌아오는 순회 여행 경로를 계획하려고 한다. 단, 한번 갔던 도시로는 다시 갈 수 없다. (맨 마지막에 여행을 출발했던 도시로 돌아오는 것은 예외) 이런 여행 경로는 여러 가지가 있을 수 있는데, 가장 적은 비용을 들이는 여행 계획을 세우고자 한다.

각 도시간에 이동하는데 드는 비용은 행렬 W[i][j]형태로 주어진다. W[i][j]는 도시 i에서 도시 j로 가기 위한 비용을 나타낸다. 비용은 대칭적이지 않다. 즉, W[i][j] 는 W[j][i]와 다를 수 있다. 모든 도시간의 비용은 양의 정수이다. W[i][i]는 항상 0이다. 경우에 따라서 도시 i에서 도시 j로 갈 수 없는 경우도 있으며 이럴 경우 W[i][j]=0이라고 하자.

N과 비용 행렬이 주어졌을 때, 가장 적은 비용을 들이는 외판원의 순회 여행 경로를 구하는 프로그램을 작성하시오.

입력

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

항상 순회할 수 있는 경우만 입력으로 주어진다.

출력

첫째 줄에 외판원의 순회에 필요한 최소 비용을 출력한다.

예제 입력 1 

4
0 10 15 20
5  0  9 10
6 13  0 12
8  8  9  0

예제 출력 1 

35

출처





- 접근 -

탐색의 탈출 조건을 설정하는 것을 가장 먼저 생각해보았다.

방문한 도시의 수가 N일때 탈출을 하는 것으로 하기로 마음 먹었다.

그리고 비용을 지속적으로 갱신해야 하기 때문에 매개변수로 비용을 넣었고, 깊이를 나타내는 idx 변수를 추가하였다.

순열 문제와 비슷하다는 느낌을 받았다.

처음에 설정이 어려워 시작하는 도시를 지정하고 문제를 생각해보았다.

<코드>

#include<stdio.h>


int w[20][20] = {0,};
int isVisited[20] = {0,};
int n,m;
int result = -1;

void dfs(int idx, int cost, int cnt)
{
  if(cnt == n){
    if(w[idx][m] != 0){
      if(result == -1 || result > cost + w[idx][m]){
        result = cost + w[idx][m]; // 교환 
      }
    }
  }
  for(int i=1; i<=n; i++){
    if(w[idx][i] != 0 && isVisited[i] == 0){
      // cost를 모두 합하고 result에 넣어 비교 하면 될거 같음
      if(result == -1 || result > cost + w[idx][i]){
        isVisited[i] = 1;
        dfs(i,cost+w[idx][i],cnt+1);
        isVisited[i] = 0;
      }
    }
  }
}

int main()
{
  scanf("%d %d",&n,&m);
  for(int i=1; i<=n; i++){
    for(int j=1; j<=n; j++){
      scanf("%d",&w[i][j]);
    }
  }
  
  result = -1;
  isVisited[m] = 1;
  dfs(m,0,1);
  printf("%d",result);
}






'알고리즘' 카테고리의 다른 글

[BOJ 1759] 암호 만들기  (0) 2019.02.22
[BOJ 2677] 단지번호 붙이기 (2)  (0) 2019.02.20
[Algorithm] 순열 복습  (0) 2019.02.19
[Algorithm] 순열 분석  (0) 2019.02.12
[BOJ 1242] 소풍  (0) 2019.02.11