zoukankan      html  css  js  c++  java
  • 欧涛最短路【记录最短路径】

    题目链接:https://ac.nowcoder.com/acm/contest/1168/C

    就是普通的最短路,建图时点的距离小于m的连双向边,自认为写了很多最短路却不知道怎么记录最短路的路径。在松弛里记录就好了,每次松弛都记录被松弛点的前驱,这样当一个点多次松弛的时候,就可以多次更新它的前驱,当它无法松弛时就是最短路径上的点,也就是记录下来的最后一次松弛的前驱。

    然后从终点开始遍历前驱,存在数组中反向输出即可输出最短路径经过的点。

    代码如下:

      1 #include<bits/stdc++.h>
      2 #define mem(a,b) memset(a,b,sizeof(a))
      3 const int MAXN = 650;
      4 const double inf = 0x3f3f3f3f * 1.0;
      5 using namespace std;
      6 
      7 int n, k;
      8 double m, dis[MAXN];
      9 int head[MAXN], cnt, vis[MAXN];
     10 int pre[MAXN]; 
     11 
     12 struct Node
     13 {
     14     double x, y, z;
     15 }node[MAXN];
     16 
     17 struct Edge
     18 {
     19     int to, next;
     20     double w;
     21 }edge[MAXN * MAXN];
     22 
     23 struct N
     24 {
     25     int pot;
     26     double dis;
     27     bool operator < (const N &a)const
     28     {
     29         return dis > a.dis;
     30     }
     31 }no;
     32 
     33 void add(int a, int b, double c)
     34 {
     35     cnt ++;
     36     edge[cnt].to = b;
     37     edge[cnt].next = head[a];
     38     edge[cnt].w = c;
     39     head[a] = cnt;
     40 }
     41 
     42 void dij()
     43 {
     44     priority_queue<N> Q;
     45     no.pot = 0, no.dis = 0;
     46     fill(dis, dis + n + 2, inf), mem(vis, 0);
     47     dis[0] = 0;
     48     Q.push(no);
     49     N a;
     50     while(!Q.empty())
     51     {
     52         a = Q.top();
     53         Q.pop();
     54         if(vis[a.pot])
     55             continue;
     56         vis[a.pot] = 1;
     57         for(int i = head[a.pot]; i != -1; i = edge[i].next)
     58         {
     59             
     60             int to = edge[i].to;
     61             if(dis[to] > dis[a.pot] + edge[i].w)
     62             {
     63                 dis[to] = dis[a.pot] + edge[i].w;
     64                 no.pot = to, no.dis = dis[to];
     65                 pre[to] = a.pot;  //松弛即更新记录,那么最后一次松弛一定更新记录到了最短路径上的点 
     66                 Q.push(no);
     67             }
     68         }
     69     }
     70 }
     71 
     72 int main()
     73 {
     74     mem(head, -1), cnt = 0;
     75     scanf("%d%lf", &n, &m);
     76     scanf("%lf%lf%lf%lf%lf%lf", &node[0].x, &node[0].y, &node[0].z, &node[n + 1].x, &node[n + 1].y, &node[n + 1].z); //起点 终点 
     77     for(int i = 1; i <= n; i ++)
     78         scanf("%lf%lf%lf", &node[i].x, &node[i].y, &node[i].z);
     79     for(int i = 0; i < n + 1; i ++)
     80     {
     81         for(int j = i + 1; j <= n + 1; j ++)
     82         {
     83             double jl = (node[i].x - node[j].x) * (node[i].x - node[j].x) + (node[i].y - node[j].y) * (node[i].y - node[j].y) + (node[i].z - node[j].z) * (node[i].z - node[j].z);
     84             if(jl <= m * m)
     85             {
     86                 add(i, j, sqrt(jl));
     87                 add(j, i, sqrt(jl));
     88             }
     89         }
     90     }
     91     dij();
     92     if(dis[n + 1] != inf * 1.0)
     93     {
     94         printf("%.3lf
    ", dis[n + 1]);
     95         printf("Start ");
     96         int p, len = 0, ans[MAXN];
     97         p = n + 1; //终点 
     98         while(p != 0) //在不等于起点时
     99         {
    100             ans[len ++] = p;
    101             p = pre[p];
    102         }
    103         for(int i=len-1;i > 0;i--)
    104             printf("%d ",ans[i]);
    105         printf("End
    ");
    106     }
    107     else
    108         printf("-1
    ");
    109     return 0;
    110 }
    记录最短路径经过的点
  • 相关阅读:
    封装和参数调用(格式修改)
    今天休息
    2018.1.9内部类
    2018.1.8转型
    环境变量
    环境变量
    计算机的高级语言
    常用的设计模式
    常用的设计模式
    【python3】中 elif 的使用
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11874527.html
Copyright © 2011-2022 走看看