题面描述
给定一张
n
(
n
≤
20
)
n(n≤20)
n(n≤20) 个点的带权无向图,点从
0
0
0 ~
n
−
1
n-1
n−1 标号,求起点
0
0
0 到终点
n
−
1
n-1
n−1 的最短Hamilton路径。 Hamilton路径的定义是从
0
0
0 到
n
−
1
n-1
n−1 不重不漏地经过每个点恰好一次。
思路
首先想到的肯定是暴力枚举,但由于时间复杂度太高,实际上是不想打
再者可以用二进制表示点,就有
2
j
2^{j}
2j表示我经历了j这个点,具体可看代码。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
int f[1<<20][20];
int map[20][20];
int main()
{
int n;scanf("%d",&n);
for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%d",&map[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^(1<<j))>>k&1)//此处表示我这个二进制数i是否包含第k位
f[i][j]=min(f[i][j],f[i^(1<<j)][k]+map[k][j]);
printf("%d\n",f[(1<<n)-1][n-1]);
return 0;
}