最短路径(paths)题解,,,水博客
2017-08-18 21:15
357 查看
题目描述:
平面内给出 n 个点,记横坐标最小的点为 A,最大的点为 B,现在小 Y 想要知道在 每个点经过一次(A 点两次)的情况下从 A 走到 B,再回到 A 的最短路径。但他是个强 迫症患者,他有许多奇奇怪怪的要求与限制条件: 1.从 A 走到 B 时,只能由横坐标小的点走到大的点。 2.由 B 回到 A 时,只能由横坐标大的点走到小的点。 3.有两个特殊点 b1 和 b2, b1 在 0 到 n-1 的路上,b2 在 n-1 到 0 的路上。 请你帮他解决这个问题助他治疗吧!
输入格式:
第一行三个整数 n,b1,b2,( 0 < b1,b2 < n-1 且 b1 <> b2)。n 表示点数,从 0 到 n-1 编号,b1 和 b2 为两个特殊点的编号。 以下 n 行,每行两个整数 x、y 表示该点的坐标(0 <= x,y <= 2000),从 0 号点顺序给出。Doctor Gao 为了方便他的治疗,已经将给出的点按 x 增序排好了。
输出格式:
输出仅一行,即最短路径长度(精确到小数点后面 2 位)
样例输入:
5 1 3 1 3 3 4 4 1 7 5 8 3
样例输出:
18.18
简析:
题目大意是:给定n个点及其坐标,要求从起点和终点相向而行,使得总距离最短,并要求包含各自的指定点,且除1,n两点外,不能包含相同点。 首先,为了方便,我们将 从n向1出发的路线视为从1向n的路线,并将点的编号加一(我实在不喜欢0到n-1)。 然后,本人用dp做的。数组f[i][j]表示线路一到达i点,线路二到达j点时的总路径长度。 为了保证不出现到达同一个点的情况,同时保证每一个点都用上,我们事先找出一个目标点,再用现在的状态去更新,来判断这个点应该加入哪一条线路,规定目标点的计算方式为 max(i,j)+1。 因此,转移方程为:(dis[i][j]表示i,j间的距离 int k=max(i,j)+1; f[1][1]=0; f[i][k]= min(f[i][k],f[i][j]+dis[j][k]) f[k][j]= min(f[k][j],f[i][j]+dis[i][k]) 当然,要考虑一些特殊情况,例如b1,b2点,k=max(i,j)+1时,(i==n||j==n)。
代码 :
#include<stdio.h> #include<string.h> #include<math.h> #define max(a,b) a>=b?a:b #define min(a,b) a>=b?b:a int scan(){ //读入优化 int x=0; char c=getchar(); while(c>'9'||c<'0') c=getchar(); while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0', c=getchar(); return x; } struct node{ int x,y; }; int n,b1,b2; node poi[1010]; double dis(int i,int j){ int x=(poi[i].x-poi[j].x)*(poi[i].x-poi[j].x); int y=(poi[i].y-poi[j].y)*(poi[i].y-poi[j].y); return sqrt(x*1.0+y*1.0); } double d[1010][1010],f[1010][1010]; int main(){ n=scan(); b1=scan()+1;b2=scan()+1; for(int i=1;i<=n;i++){ poi[i].x=scan(); poi[i].y=scan(); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ d[i][j]=d[j][i]=dis(i,j); f[i][j]=20000010.0; } f[1][1]=0.0; //都在起点时距离为0 //已经将从n到1视为从1到n for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if(i!=j||i==1){ int k= max(i,j) ; k++; if(k==n+1){ //线路一或线路二到达终点 if(i!=n) f = min(f ,f[i][j]+d[i] ); if(j!=n) f = min(f ,f[i][j]+d[j] ); continue; } if(k!=b1) //b1只能在线路一,因此,将k加入线路二时,要看一下k是不是b1 f[i][k]= min(f[i][k],f[i][j]+d[j][k]); if(k!=b2) //同理 f[k][j]= min(f[k][j],f[i][j]+d[i][k]); } } printf("%.2lf",f ); //保留两位小数 }
相关文章推荐
- C++生成最短路径的贪心算法SHORTEST_PATHS
- 2011-02-28 CLRS Chapter25 All-Pairs Shortest Paths 每对顶点间的最短路径
- 最短路径算法(Shortest Paths Algorithm)
- 算法导论 单源最短路径 DAG-SHORTEST-PATHS
- 使用GraphFrame 的shortestPaths API 求最短路径
- Spark组件之GraphX学习16--最短路径ShortestPaths
- 怎样通过boost库的breadth_first_search算法查找点到点的最短路径
- 最短路径算法——邻接距阵
- 最短路径问题
- 最短路径算法
- Floyed算法实现最短路径
- 71.双向最短路径:聚会
- POJ 1797 Heavy Transportation(最短路径中的最大权值边)
- ZOJ 2760--How Many Shortest Path【dinic最大流 && 最短路构图 && 求最短路径的条数】
- 最短路径
- hdu 2433 Travel(最短路径树+删边+bfs)
- hdu 最短路径
- 【图算法】(4)最短路径算法
- 图论-BFS解无权有向图最短路径距离
- POJ 1062 昂贵的聘礼(最短路径Dijkstra+枚举)