求点1经过其他各点一次并回到1的最小路径和。
n
<
=
20
n<=20
n<=20
设
f
s
,
i
f_{s,i}
fs,i表示经过的点集为
s
{s}
s,最后一步走到了点
i
i
i的最小路径和
a
n
s
=
m
i
n
(
f
(
1
<
<
n
)
−
1
,
i
+
d
i
s
i
,
1
)
ans= min(f_{(1<<n)-1,i}+dis_{i,1})
ans=min(f(1<<n)−1,i+disi,1)
时间复杂度:
O
(
2
n
n
2
)
O(2^nn^2)
O(2nn2)
感觉超时的但是居然过了
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
int n, a[N][N];
int f[1<<20][N];
int main() {
// freopen("data.in", "r", stdin);
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) cin >> a[i][j];
memset(f, 0x3f, sizeof(f));
f[1][0] = 0;
for (int i = 1; i < (1 << n); i++) {
for (int j = 0; j < n; j++)
if ((i >> j) & 1) {
for (int k = 0; k < n; k++)
if (!((i >> k) & 1)) f[i | (1 << k)][k] = min(f[i | (1 << k)][k], f[i][j] + a[j][k]);
}
}
int ans = 2e9;
for (int i = 1; i < n; i++) ans = min(ans, f[(1 << n) - 1][i] + a[i][0]);
printf("%d\n", ans);
return 0;
}