欧涛最短路 (三维坐标)

链接: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”(无双引号)
示例1

输入

复制
4 5
0 0 0 6 6 0 
-1 1 0
5 6 0
3 4 0 
6 1 0

输出

复制
8.606
Start 3 End

备注:

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\n",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;
}

 




posted @ 2019-11-24 21:03  知道了呀~  阅读(390)  评论(0编辑  收藏  举报