POJ 2677 tour(双调欧几里得旅行商问题)
2015-03-23 19:48
281 查看
思路(转载):
欧几里得旅行商问题是对平面上给定的n个点确定一条连接各点的最短闭合旅程的问题。如图(a)给出了一个7个点问题的解。这个问题的一般形式是NP完全的,故其解需要多于多项式的时间。J.L. Bentley 建议通过只考虑双调旅程(bitonic tour)来简化问题,这种旅程即为从最左点开始,严格地从左到右直至最右点,然后严格地从右到左直至出发点。下图(b)显示了同样的7个点的最短双调路线。在这种情况下,多项式的算法是可能的。事实上,存在确定的最优双调路线的O(n*n)时间的算法。
图a
图b
注:在一个单位栅格上显示的平面上的七个点。 a)最短闭合路线,长度大约是24.89。这个路线不是双调的。b)相同点的集合上的最短双调闭合路线。长度大约是25.58。
这是一个算导上的思考题15-1。
首先将给出的点排序,关键字x,重新编号,从左至右1,2,3,…,n。
定义p[i][j]p[i][j],表示结点i到结点j之间的距离。
定义d[i][j]d[i][j],表示从i连到1,再从1连到j,(注意,i>j,且并没有相连。)
对于任意一个点i来说,有两种连接方法,一种是如图(a)所示,i与i-1相连,另一种呢是如图(b),i与i-1不相连。
根据双调旅程,我们知道结点n一定与n相连,那么,如果我们求的d
[n-1],只需将其加上p[n-1]
就是最短双调闭合路线。
根据上图,很容易写出方程式:
dp[i][j]=dp[i−1][j]+dist[i][i−1];dp[i][j]=dp[i-1][j]+dist[i][i-1];
dp[i][i−1]=min(dp[i][i−1],dp[i−1][j]+dist[j][i]);dp[i][i-1]=min(dp[i][i-1],dp[i-1][j]+dist[j][i]);
注意
G++浮点数的标准输出是 %f ,而C++浮点数的标准输出%lf,在这边会被坑到。AC代码:
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e3; struct Point { double x, y; }point ; double dp ; bool cmp(Point a, Point b) { if(a.x != b.x) return a.x < b.x; return a.y < b.y; } inline double dis(int i, int j) { double x = point[i].x - point[j].x; double y = point[i].y - point[j].y; return sqrt(x*x + y*y); } /* dp[i+1][j] = dp[i][j] + dis(i,i+1); dp[i+1][i] = min(dp[i][j] + dis(j, i+1)) */ double tsp(int n) { for(int i = 1; i <= n; i++) { for(int j = 1; j < i; j++) { dp[i][j] = dp[j][i] = INF; } } for(int i = 1; i <= n; i++) { dp[i][1] = dis(i, 1); } for(int i = 2; i < n; i++) { for(int j = 1; j < i; j++) { dp[i+1][j] = dp[i][j] + dis(i, i+1); dp[i+1][i] = min(dp[i+1][i], dp[i][j] + dis(j, i+1)); } } return dp [n-1] + dis(n, n-1); } int main() { int n; while(scanf("%d", &n) != EOF) { for(int i = 1; i <= n; i++) { scanf("%lf%lf", &point[i].x, &point[i].y); } sort(point+1, point+1+n, cmp); double ans = tsp(n); printf("%.2f\n", ans); } return 0; }
相关文章推荐
- UVA 1347(POJ 2677)Tour(双调欧几里得旅行商问题)
- POJ-2677 Tour(双调欧几里得旅行商问题)(动态规划)
- UVA 1347(POJ 2677) Tour(双调欧几里得旅行商问题)
- [ACM] POJ 2677 Tour (动态规划,双调欧几里得旅行商问题)
- POJ 2677 (算法导论15-3)双调欧几里得旅行商问题 dp
- poj 2677 双调欧几里得旅行商问题
- poj 2677 Tour(双调欧几里德旅行商问题,dp)
- 双调欧几里得旅行商问题 Bitonic_TSP poj 2677
- 双调欧几里得旅行商问题解法 (POJ 2677)
- POJ 2677 双调欧几里得旅行商问题
- UVALive - 3305 Tour 双调欧几里得旅行商问题
- 双调欧几里得旅行商问题【sicily 1163 && poj 2677.Tour】
- POJ 2677 Tour 双调旅行商 dp, double+费用流
- 1347 - Tour (双调欧几里得旅行商问题)
- POJ 2677 旅行商问题 双调dp或者费用流
- UVA - 1347 Tour 双调欧几里得旅行商问题
- 双调欧几里得旅行商问题 UVA 1347 Tour
- UVA 1347 Tour(双调欧几里得旅行商问题)
- UVA 1347(POJ 2677) Tour(双色欧几里德旅行商问题)
- UVA1347-Tour 双调欧几里得旅行商问题 - 递归记忆实现