题目:
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=20,M=1<<N;
int n;
int w[N][N];
int f[M][N];
//f[i][j]代表路径为i,到达j点的最短路径
//i的二进制从低位到高位每一位0,1依次代表0~n个点是否走过
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&w[i][j]);
}
}
memset(f,0x3f,sizeof f);
f[1][0]=0;
//第一层循环枚举出每一种状态
for(int i=0;i<1<<n;i++){
//第二层循环枚举每一个终点
for(int j=0;j<n;j++){
//在终点为j的所有状态中合法的是路线中确实经过了j这个点的状态
if(i>>j&1){
for(int k=0;k<n;k++){
//这个合法性判断与上面的相似,经过了k这个点再到达到达j终点这个点合法状态是状态中在经过了j这个点的同时也经过了k这个点
if(i>>k&1){
f[i][j]=min(f[i][j],f[i-(1<<j)][k]+w[k][j]);
}
}
}
}
}
printf("%d",f[(1<<n)-1][n-1]);
return 0;
}