旅行商

旅行商

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;
}



你可能感兴趣的:(旅行商)