/* f[i][j] 表示走过的点构成i状态 且最后到达的点为j时的最优解 在那最后一个状态就是(1<<n+1)-1 每个点都到达 在由此回到0 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100010//最少到 1<<16 using namespace std; int n,g[20][20],f[maxn][20],ans=0x3f3f3f3f; int main() { scanf("%d",&n); for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&g[i][j]); for(int k=0;k<=n;k++) for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) g[i][j]=min(g[i][k]+g[k][j],g[i][j]); memset(f,127/3,sizeof(f));f[1][0]=0;//初始化 for(int i=1;i<=(1<<n+1)-1;i++)//枚举走过点构成的状态 for(int j=0;j<=n;j++)//枚举最后一次到达的点 if((1<<j)&i)//j 走过了 { for(int k=0;k<=n;k++) f[i|(1<<k)][k]=min(f[i|(1<<k)][k],f[i][j]+g[j][k]); } for(int i=1;i<=n;i++) ans=min(ans,g[i][0]+f[(1<<n+1)-1][i]); printf("%d\n",ans); return 0; }
时间: 2024-10-23 01:15:11