题目传送门:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int dp[1<<20][24];//dp[i][j],状态为i的且路过j的路的最小值
int g[24][24];//存储各个点之间的距离
int main()
{
memset(dp,0x3f,sizeof(dp));//先赋值两点之间的距离为最大
int n;
cin>>n;
dp[1][0]=0;//自己到自己的距离为0
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>g[i][j];
}
}
for(int i=0;i<(1<<n);i++)//遍历所有可能存在的状态
for(int j=0;j<n;j++)//遍历所有点
{
if(!((i>>j)&1)) continue;//判断这个点在这个状态中是否路过
for(int k=0;k<n;k++)//再次遍历一遍点
{
if(j==k) continue;//自己到自己的距离为0,直接跳过
if(!((i>>k)&1)) continue;//这个点不在此状态中直接跳过
dp[i][j]=min(dp[i][j],dp[i^(1<<j)][k]+g[k][j]);//状态转移方程
}
}
int ans=0x3f3f3f;
for(int i=0;i<n;i++)
{
ans=min(ans,dp[(1<<n)-1][i]+g[i][0]);//在所有状态为全1中寻找最小值
}
cout<<ans<<endl;
return 0;
}