πŸ•οΈ ICPC Sinchon/Backtracking

[BOJ S2][C++] λ°±μ€€ 10971번: μ™ΈνŒμ› 순회 2

선달 2022. 9. 27. 03:53
λ°˜μ‘ν˜•

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

 

10971번: μ™ΈνŒμ› 순회 2

첫째 쀄에 λ„μ‹œμ˜ 수 N이 주어진닀. (2 ≤ N ≤ 10) λ‹€μŒ N개의 μ€„μ—λŠ” λΉ„μš© 행렬이 주어진닀. 각 ν–‰λ ¬μ˜ 성뢄은 1,000,000 μ΄ν•˜μ˜ μ–‘μ˜ μ •μˆ˜μ΄λ©°, 갈 수 μ—†λŠ” κ²½μš°λŠ” 0이 주어진닀. W[i][j]λŠ” λ„μ‹œ iμ—μ„œ j

www.acmicpc.net

 

문제

μ™ΈνŒμ› 순회 λ¬Έμ œλŠ” μ˜μ–΄λ‘œ 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 ≤ 10) λ‹€μŒ N개의 μ€„μ—λŠ” λΉ„μš© 행렬이 주어진닀. 각 ν–‰λ ¬μ˜ 성뢄은 1,000,000 μ΄ν•˜μ˜ μ–‘μ˜ μ •μˆ˜μ΄λ©°, 갈 수 μ—†λŠ” κ²½μš°λŠ” 0이 주어진닀. W[i][j]λŠ” λ„μ‹œ iμ—μ„œ j둜 κ°€κΈ° μœ„ν•œ λΉ„μš©μ„ λ‚˜νƒ€λ‚Έλ‹€.

항상 μˆœνšŒν•  수 μžˆλŠ” 경우만 μž…λ ₯으둜 주어진닀.

좜λ ₯

첫째 쀄에 μ™ΈνŒμ›μ˜ μˆœνšŒμ— ν•„μš”ν•œ μ΅œμ†Œ λΉ„μš©μ„ 좜λ ₯ν•œλ‹€.

 

풀이

40% μ—μ„œ ν‹€λ ΈμŠ΅λ‹ˆλ‹€ κ°€ λ‚˜μ˜€λ©΄...
w[i][j]κ°€ 0인경우 iμ—μ„œ j둜 갈 수 μ—†λ‹€λŠ” 점을 κ΅¬ν˜„ν•΄μ£Όμž...

// Authored by : seondal
// Co-authored by : -

// #include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int n;
vector<vector<int>> input;
vector<bool> isVisit;  // 지역 i의 λ°©λ¬Έ μ—¬λΆ€
vector<int> cost;  // κ°€λŠ₯ν•œ 이동 λΉ„μš©λ“€

void recur(int start, int cur, int cnt, int sum){
    // n개 지역을 μ „λΆ€ λ°©λ¬Έν–ˆκ³ , μΆœλ°œμ§€λ‘œ λŒμ•„κ°ˆ 수 μžˆλ‹€λ©΄
    if(cnt==n && input[cur][start]!=0) {
        sum += input[cur][start];
        cost.push_back(sum);
        return;
    }
    
    for(int i=0; i<n; i++) { // λ‹€μŒ 행선지 μ°ΎκΈ°
        if(isVisit[i] || input[cur][i]==0)  // 이미 λ°©λ¬Έν–ˆκ±°λ‚˜ 갈 수 μ—†λ‹€λ©΄ 패슀
            continue;
        isVisit[i] = true;
        recur(start, i, cnt+1, sum+input[cur][i]);
        isVisit[i] = false;
    }
}

int solution() {
    for(int i=0; i<n; i++) {
        isVisit[i] = true;
        recur(i,i,1,0);
        isVisit[i] = false;
    }
    
    sort(cost.begin(), cost.end());
    int minCost = cost[0];
    
    return minCost;
}

int main() {
    cin >> n;
    input.assign(n, vector<int>(n,0));
    isVisit.assign(n, false);
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            cin >> input[i][j];

    cout << solution();
    
    return 0;
}

/*
 */
λ°˜μ‘ν˜•