本题可以暴力状压DP
设 f i , j f_{i,j} fi,j 表示当前在i点上,把到过的点表示为1,没到过的点表示为0,压成二进制为j的方案数。
枚举两个点直接转移就好了。
#include
#include
#include
using namespace std;
int n,f[30][1<<21],a[30][30];
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&a[i][j]);
memset(f,0x3f,sizeof(f));
f[1][1]=0;
for(int i=0; i<=(1<<n); i++)
{
for(int j=1; j<=n; j++)
{
if(!((i>>j-1)&1))
continue;
int q=i^(1<<j-1);
for(int k=1; k<=n; k++)
{
if(i&(1<<k-1)&&k!=j)
f[j][i]=min(f[j][i],f[k][q]+a[k][j]);
}
}
}
printf("%d",f[n][(1<<n)-1]);
return 0;
}