题目链接
http://noi-test.zzstep.com/contest/0x00%E3%80%8C%E5%9F%BA%E6%9C%AC%E7%AE%97%E6%B3%95%E3%80%8D%E4%BE%8B%E9%A2%98/0103%20%E6%9C%80%E7%9F%ADHamilton%E8%B7%AF%E5%BE%84
分析
状压DP,状态 f [ i ] [ j ] f[i][j] f[i][j] 用 n n n 位二进制数 i i i 来表示每个点是否被经过,同时 j j j 记录当前路径终点,每次枚举 j j j 的前一个点,确定上一状态,转移即可,注意求最小值,先将 f f f 数组置为正无穷,令 f [ 1 ] [ 0 ] = 0 f[1][0] = 0 f[1][0]=0。
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 25;
int n, d[maxn][maxn], f[1 << 20][maxn];
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j) scanf("%d", &d[i][j]);
memset(f, 0x3f, sizeof(f));
f[1][0] = 0;
for (int i = 2; i < (1 << n); ++i)
for (int j = 0; j < n; ++j) if ((i >> j) & 1)
for (int k = 0; k < n; ++k) if (k != j && ((i >> k) & 1))
f[i][j] = min(f[i][j], f[i ^ (1 << j)][k] + d[k][j]);
printf("%d", f[(1 << n) - 1][n - 1]);
return 0;
}