题意是求穿过n个城市后返回的最短路程,n为城市数,一个n*n的数组,第i行第j列表示从i城市到j城市中间不经过其他城市所需的路程,所以要先求最短路,然后根据此时的状态i求出到j城市所需的最短路程,返回时直接返回
这个的状态需要用二进制表示,容易出错
代码在这:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int dis[20][20];
int dp[1<<11][20];
int main()
{
int n;
int ans;
while(scanf("%d",&n)&&n!=0)
{
memset(dis,0,sizeof(dis));
memset(dp,0,sizeof(dp));
ans=1e9;
for(int i=0;i<n+1;++i)
for(int j=0;j<n+1;++j)
scanf("%d",&dis[i][j]);
for(int i=0;i<=n;++i)
for(int j=0;j<=n;++j)
{
for(int k=0;k<=n;++k)
dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
}
for(int i=0;i<(1<<n);++i)
for(int j=1;j<=n;++j)
{
if(i==(1<<(j-1))) dp[i][j]=dis[0][j];
else
{
if(i&(1<<(j-1)))
{
dp[i][j]=1e9;
for(int k=1;k<=n;++k)
{
if(k!=j&&(i&(1<<(k-1))))
dp[i][j]=min(dp[i][j],dp[i^(1<<(j-1))][k]+dis[k][j]);
}
}
}
}
for(int i=1;i<=n;++i)
ans=min(ans,dp[(1<<n)-1][i]+dis[i][0]);
printf("%d\n",ans);
}
return 0;
}