题目链接:http://poj.org/problem?id=3311
题目大意:问一个售货员 从第1个城市出发,遍历所有城市,回到原点的花费。
经典旅行商问题。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int dp[1100][11],dis[13][13];
int n;
void init()
{
memset(dp,0,sizeof(dp));
memset(dis,inf,sizeof(dis));
}
void floyd()
{
for(int k = 0; k <= n; ++k)
for(int i = 0; i <= n; ++i)
for(int j = 0; j <= n; ++j)
if(dis[i][k] + dis[k][j] < dis[i][j])
dis[i][j] = dis[i][k] + dis[k][j];
}
void solve()
{
int num=(1<<n);
for(int i=0; i<num; i++)
for(int j=1; j<=n; j++)
{
if( i&(1<<(j-1)) )
{
if( i==(1<<(j-1)) ) //初始化
dp[i][j]=dis[0][j];
else
{
dp[i][j]=inf;
for(int k=1;k<=n;k++)
if( i&(1<<(k-1)) && j!=k)
dp[i][j]=min(dp[i][j],dp[ i-(1<<(j-1)) ][k]+dis[k][j]);
}
}
}
int ans=inf;
for(int i=1;i<=n;i++)
ans=min(ans,dp[(1<<n)-1][i]+dis[i][0]);
printf("%d\n",ans);
}
int main()
{
while(scanf("%d",&n)&&n)
{
init();
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
scanf("%d",&dis[i][j]);
floyd();
solve();
}
return 0;
}
/*
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
8
*/