【回溯法】旅行商问题

Description

     
 

 “旅行商问题”常被称为“旅行推销员问题”,是指一名推销员要拜访多个地点时,如何找到在拜访每个地点一次后再回到起点的最短路径。现在有n个城市,部分城市间有路相连。请找出从第一个城市出发,访问且只访问每个城市一次,并回到第一个城市的最短路径长度。

 
     

Input

     
 
第一行是城市个数n,n<= 20。以下n行,每行n个整数,第i行的第j个数字代表城市i到城市j的距离。距离-1代表两个城市间没有路。
 
     

Output

     
 
输出最短路径长度。如果找不到遍历的路,输出“No Solution”。
 
     

Sample Input

     
 
4
0 30 6 4
30 0 5 10
6 5 0 20
4 10 20 0
 
     

Sample Output

     
 
25
 
 

#include <iostream>
#include <climits>
using namespace std;
#define N 25
int d[N][N];
int x[N];
int cc,n;
int bestc=INT_MAX;
int sum;

void backtrack(int t)
{
	if(t>n)
	{
		if(d[x[n]][1] > 0 && cc+d[x[n]][1] < bestc || bestc==0)
		{
			bestc=cc+d[x[n]][1];
			sum++;
		}
	}
	else
	{
		for(int i=t;i<=n;i++)
		{
			if(d[x[t-1]][x[i]] > 0 && cc + d[x[t-1]][x[i]] < bestc || bestc==0)
			{
				swap(x[t],x[i]);
				cc+=d[x[t-1]][x[t]];
				backtrack(t+1);
				cc-=d[x[t-1]][x[t]];
				swap(x[t],x[i]);
			}
		}
	}
}

int main() 
{
	int i,j;
	while(cin>>n)
	{
		sum=0;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				cin>>d[i][j];
		for(i=1;i<=n;i++)
			x[i]=i;
		backtrack(2);
		if(sum==0)
			cout<<"No Solution"<<endl;
		else
			cout<<bestc<<endl;
	}
	return 0;
}
    原文作者:回溯法
    原文地址: https://blog.csdn.net/momo_unique/article/details/37573141
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞