旅行商
Time Limit: 1000 msCase Time Limit:1000 msMemory Limit: 64 MB
Total Submission: 238Submission Accepted: 67
Description
旅行商问题描述如下:在一个无向图中,找到符合条件的最小长度回路,这个回路经过每一个结点一次。
Input
第一行:一个正整数N,1<=N<=15
第2至1+N行:整数临接矩阵,第i行第j列代表从结点i到结点j的路程,i=j时路程为0,其他情况1<=路程<100
Output
第一行:一个整数,旅行商问题的最优回路长度
Sample Input
Original | Transformed |
3
0 17 81
17 0 62
81 62 0
Sample Output
Original | Transformed |
160
状态压缩DP,调试了一个多小时,后来发现if((i&cur)==0)和 if(i&cur==0)不一样,原来==的优先级比&高
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
#define N 1<<15
#define INF 99999999
int dp[N][15];
int start[N][15];
int map[20][20];
int main()
{
int n,i,j,k;
int upper,cur,min,curtemp,temp;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&map[i][j]);
upper=(1<<n)-1;
for(i=0;i<=upper;i++)
for(j=0;j<n;j++)
dp[i][j]=INF;
for(i=0;i<n;i++)
{
dp[0][i]=0;
start[0][i]=i;
}
for(i=0;i<upper;i++)
{
for(j=0;j<n;j++)
{
for(k=0;k<n;k++)
{
cur=1<<k;
if((i&cur)==0)
{
curtemp=i|cur;
if(dp[i][j]+map[j][k]<dp[curtemp][k])
{
dp[curtemp][k]=dp[i][j]+map[j][k];
start[curtemp][k]=start[i][j];
}
}
}
}
}
min=INF;
for(i=0;i<n;i++)
{
temp=start[upper][i];
if(dp[upper][i]+map[i][temp]<min)
min=dp[upper][i]+map[i][temp];
}
printf("%d\n",min);
}
return 0;
}