uva 1347(双调欧几里得旅行商问题)
2015-07-25 17:29
435 查看
题意:一个人要去n个地方旅行,给出n个点的坐标,他会从最左边的点走到最右边,然后再回到起点,除了最左边和最右边两个点,每个点只经过一次。问最短路。
题解:f[i][j]表示从i到1再从1到j连通的最短路。
状态转移方程:
f[i][j] = f[i - 1][j] + dist(p[i - 1], p[i])
f[i][i - 1] = min(f[i][i - 1], f[i - 1][j] + dist(p[j], p[i]))
题解:f[i][j]表示从i到1再从1到j连通的最短路。
状态转移方程:
f[i][j] = f[i - 1][j] + dist(p[i - 1], p[i])
f[i][i - 1] = min(f[i][i - 1], f[i - 1][j] + dist(p[j], p[i]))
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 105; const double INF = 10000000000000; struct Point { int x, y; }p ; int n; double f ; double dist(const Point& a, const Point& b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } int main() { while (scanf("%d", &n) == 1) { for (int i = 0; i < n; i++) scanf("%d%d", &p[i].x, &p[i].y); for (int i = 0; i < n; i++) for (int j = i; j < n; j++) f[i][j] = f[j][i] = 0; f[0][0] = 0; for (int i = 1; i < n; i++) { f[i][i - 1] = INF; f[i][0] = dist(p[i], p[0]); for (int j = 0; j < i - 1; j++) { f[i][j] = f[i - 1][j] + dist(p[i], p[i - 1]); f[i][i - 1] = min(f[i][i - 1], f[i - 1][j] + dist(p[i], p[j])); } } printf("%.2lf\n", f[n - 1][n - 2] + dist(p[n - 1], p[n - 2])); } return 0; }
相关文章推荐
- Android模拟器运行缓慢解决办法
- linux初学(三)之 文件基本操作管理
- 括号匹配
- struts 属性驱动
- 九度oj 1201
- leetcode | Merge Intervals
- error:unknown field 'ioctl' specified in initializer
- TextView下划线,中划线,抗锯齿
- 在Fragment中重写返回键以及WebView加载重定向页面返回问题
- error C2044: illegal continue!break 和continue的用法
- 【Java】 Base64原理及简单应用
- 字符串和字节的相互转换
- 合理处理jdbc中的异常
- 【HTML学习】新的结构化元素
- 数据库语句
- 基于MFC与第三方类CWebPage的百度地图API开发范例
- codeforces(559C)--C. Gerald and Giant Chess(组合数学)
- Smart Health 2015 Call for Papers
- Visual Studio我常用的快捷键
- EularProject 43: 带条件约束的排列组合挑选问题