[백준 2098번 C/C++] 외판원 순회
[백준 2098번 C/C++] 외판원 순회
https://www.acmicpc.net/problem/2098
해결전략
비트마스킹 Bitmasking
동적계획법 Dynamic Programming, DP
비트필드를 이용한 다이나믹 프로그래밍
외판원 순회 문제
정답 코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n; // 도시의 수
vector<vector<int>> W;
vector<vector<int>> dp;
const int INF = 2147000000;
int TSP(int cur, int visited)
{
// visited의 모든 비트가 1이라면(즉, 모든 도시를 방문했다면), 현재 도시에서 시작 도시로 돌아가는 비용을 반환
if (visited == (1 << n) - 1) {
return W[cur][0] ? W[cur][0] : INF;
}
// 이미 계산된 적이 있는 경우 캐싱된 값을 반환
int& ret = dp[cur][visited];
if (ret != -1) return ret;
ret = INF; // 초기값을 무한대로 설정
for (int next = 0; next < n; next++) // 모든 도시에 대해
{
// 아직 방문하지 않았고, 길이 있는 경우
if (!(visited & (1 << next)) && W[cur][next] != 0) {
// 현재 도시에서 다음 도시로 가는 비용 + 다음 도시에서의 최소 비용 계산
ret = min(ret, TSP(next, visited | (1 << next)) + W[cur][next]);
}
}
return ret; // 계산된 값을 반환하며, 동시에 dp[cur][visited]에 저장됨
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
W.resize(n, vector<int>(n));
dp.resize(n, vector<int>(1 << n, -1));
for (int y = 0; y < n; y++) {
for (int x = 0; x < n; x++) {
cin >> W[y][x];
}
}
int answer = TSP(0, 1);
cout << (answer == INF ? -1 : answer) << endl;
return 0;
}
visited | (1 << next)의 의미
- visited: 현재까지 방문한 도시들을 비트마스크로 표현한 값입니다.
- 1 << next
- 1을 next 비트만큼 왼쪽으로 이동시킨 값.
- 이는 next 도시를 방문했음을 의미하는 비트마스크다.
- 예를 들어, next가 2라면 1 << 2는 0100(2진수).
- visited | (1 << next)
- 현재 방문 상태인 visited에 next 도시를 추가로 방문했음을 기록한 새로운 비트마스크.
- 예를 들어, visited가 1101이고 next가 1이라면, 1 << 1은 0010이 되고, visited | (1 << next)는 1101 | 0010이 되어 1111(2진수)가 됩니다. 이는 0번, 1번, 2번, 3번 도시를 모두 방문했음을 의미함.
+ W[cur][next]의 의미
- W[cur][next]
- 현재 도시 cur에서 다음 도시 next로 가는 비용.
- TSP(next, visited | (1 << next)) + W[cur][next]:
- TSP(next, visited | (1 << next)): next 도시를 방문한 후, 나머지 도시들을 모두 방문하는 최소 비용.
- + W[cur][next]: 현재 도시 cur에서 next 도시로 가는 비용을 더한 전체 비용.
ret = min(ret, TSP(next, visited | (1 << next)) + W[cur][next])
현재 도시 cur에서 아직 방문하지 않은 도시 next로 이동한 후, 모든 도시를 방문하는 최소 비용을 계산
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 20055번 C/C++] 컨베이어 벨트 위의 로봇 (0) | 2024.08.23 |
---|---|
[백준 1062번 C/C++] 가르침 (0) | 2024.08.19 |
[백준 14391번 C/C++] 종이 조각 (0) | 2024.08.07 |
[백준 15661번 C++] 링크와 스타트 (0) | 2024.08.06 |
[백준 11723번 C/C++] 집합 (0) | 2024.08.05 |
댓글
이 글 공유하기
다른 글
-
[백준 20055번 C/C++] 컨베이어 벨트 위의 로봇
[백준 20055번 C/C++] 컨베이어 벨트 위의 로봇
2024.08.23 -
[백준 1062번 C/C++] 가르침
[백준 1062번 C/C++] 가르침
2024.08.19 -
[백준 14391번 C/C++] 종이 조각
[백준 14391번 C/C++] 종이 조각
2024.08.07 -
[백준 15661번 C++] 링크와 스타트
[백준 15661번 C++] 링크와 스타트
2024.08.06