题目位置:https://www.acwing.com/problem/content/description/93/
给定一张 n 个点的带权无向图,点从 0∼n−1 标号,求起点 0 到终点 n−1的最短 Hamilton 路径。
Hamilton 路径的定义是从 0到 n−1 不重不漏地经过每个点恰好一次。
//核心公式:f[i,j]=min(f[i][j],f[i^1<<j][k]+weight[k][j])
#include<iostream>
#include<cstring>
using namespace std;
int n;
//f[i][j] 若其第i位为1,则表示第i个点已经被经过,反之未被经过
// j:目前处于点j时的最短路径
int f[1<<20][20];
int weight[21][21];//权重
int main()
{
cin>>n;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
cin>>weight[i][j];
memset(f,0x3f,sizeof f);
f[1][0]=0;//因为零是起点,所以f[1][0]=0;
for(int i=1; i<1<<n; i++)
for(int j=0; j<n; j++)//j表示走到哪一个点
if(i>>j&&1)
for(int k=0; k<n; k++)//k表示走到j这个点之前,以k为终点的最短距离
if((i^1<<j)>>k&1)
f[i][j]=min(f[i][j],f[i^1<<j][k]+weight[k][j]);
cout<<f[(1<<n)-1][n-1];//表示所有点都走过了,且终点是n-1的最短距离
return 0;
}