您的位置:首页 > 其它

hdu 2224 The shortest path

2014-05-26 11:17 281 查看
本题归结为旅行推销员问题(Travelling Salesman Problem, 又称为旅行商问题、货郎担问题、TSP问题)是一个多局部最优的最优化问题:有n个城市,一个推销员要从其中某一个城市出发,唯一走遍所有的城市,再回到他出发的城市,求最短的路线。

研究NP问题时看到了计算欧式平面最短哈密顿回路的贪心算法, 只能得到近似解

此算法在本题上得到了应用

具体求解步骤为将计算简化为求出最短双调TSP回路, 将所有点按x坐标排序后, 先从最左端点向右走按递增顺序达到最右端点然后再按递减顺序走回, 因为期间没有折返, 所以可以保证x方向局部最优.

由于题目给出的点已经按x坐标排序, 所以可以省去排序这一步

这种贪心算法的优势在于时间效率, 如果要得到最优解, 需要枚举每两个点, 算法复杂度将达到

. 如果利用动态规划则可以达到

 但仍然太慢

利用双调TSP回路计算, 在应用动归时算法复杂度只有


对于其他的TSP求解方法可以参见:

http://episte.math.ntu.edu.tw/articles/mm/mm_11_3_02/index.html

具体算法图示可见http://en.wikipedia.org/wiki/Travelling_salesman_problem

/*author: birdstorm*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <climits>

#define MAXN 205
#define N 105
#define inf 1.0e20
#define eps 1.0e-10
#define MOD 1000000007

#define For(i,m,n) for(int i=(m);i<(n);i++)
#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)
#define rep(i,m,n) for(int i=(m);i<=(n);i++)
#define LL long long

using namespace std;
pair<int,int> p[MAXN];
double dp[MAXN][MAXN], dist[MAXN][MAXN];

double dis(int x, int y)
{
double t1=p[x].first-p[y].first;
double t2=p[x].second-p[y].second;
return sqrt(t1*t1+t2*t2);
}
int main()
{
int n;
while(~scanf("%d",&n)){
double ans=inf;
rep(i,1,n) scanf("%d%d",&p[i].first,&p[i].second);
rep(i,2,n) rep(j,1,i-1) dist[i][j]=dis(i,j);
dp[2][1]=dist[2][1];
rep(i,3,n){
rep(j,1,i-2) dp[i][j]=dp[i-1][j]+dist[i][i-1];
dp[i][i-1]=inf;
rep(j,1,i-2) dp[i][i-1]=min(dp[i-1][j]+dist[i][j],dp[i][i-1]);
if(i==n) dp[i][i]=dp[i][i-1]+dist[i][i-1];
}
printf("%.2lf\n",dp

);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: