链接:https://ac.nowcoder.com/acm/contest/1168/C
来源:牛客网
题目描述
已知了飞行器的起点和终点以及n个休息站的坐标,问起点到终点的最短路径是多少?
限制:飞行器不能长期飞行,必须中途在某结点下停下休息。(即连续飞行距离应不大于m)
欧涛师兄很想在师妹面前大展身手,你能帮助他解决这个问题吗?
输入描述:
第一行输入两个数,整数n和浮点数m
第二行输入六个浮点数x1,y1,z1,x2,y2,z2。分别代表起点坐标(x1,y1,z1)和终点坐标(x2,y2,z2)
紧接着下面n行,每行依次输入三个浮点数,代表休息站的坐标(ai,bi,ci),休息站编码依次为1,2……n。
输出描述:
输出满足条件的起点到终点的最短距离长度(结果保留三位小数)。
依次输出飞行器经过站台的编码(休息站编码为1到n,起点编码Start,终点编码End)
若不能到达终点输出“-1”(无双引号)
备注:
n<=600
先用坐标预处理出路径权值
#include<iostream> #include<algorithm> #include<math.h> #include<stack> #include<string> #include<string.h> #define ll long long #define M 999999999 using namespace std; struct node { double x; double y; double z; }p[1000]; double way[1000][1000],dis[1000]; int next1[1000],vis[1000]; int n; double m; stack<int>s; double len(node a, node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)); } void Dijkstra(int s) { for(int i=0;i<=n+1;i++) { dis[i]=way[s][i]; } vis[s]=1; for(int i=0;i<=n+1;i++) { int minn=M,k=0; for(int j=0;j<=n+1;j++) { if(!vis[j]&&dis[j]<minn) { minn=dis[j]; k=j; } } if(minn==M) { break; } vis[k]=1; for(int j=0;j<=n+1;j++) { if(!vis[j]) { if(dis[j]>way[k][j]+dis[k]) { dis[j]=way[k][j]+dis[k]; next1[j]=k; } } } } } int main() { cin>>n>>m; next1[0]=-8; memset(way,M,sizeof(way)); cin>>p[0].x>>p[0].y>>p[0].z>>p[n+1].x>>p[n+1].y>>p[n+1].z; for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y>>p[i].z; for(int i=0;i<=n+1;i++) { for(int j=0;j<=n+1;j++) { way[i][j]=len(p[i],p[j]); if(way[i][j]>m) way[i][j]=M; } } // for(int i=0;i<=n+1;i++) // for(int j=0;j<=n+1;j++) // cout<<way[i][j]<<endl; Dijkstra(0); if(dis[n+1]==M) cout<<-1<<endl; else { //cout<<dis[n+1]<<endl; printf("%.3lf ",dis[n+1]); int cnt=n+1; while(next1[cnt]!=-8) { s.push(cnt); cnt=next1[cnt]; } cout<<"Start"; while(s.size()!=1) { cout<<' '<<s.top(); s.pop(); } cout<<" "<<"End"<<endl; } return 0; }