zoukankan      html  css  js  c++  java
  • 【洛谷P1491】集合位置

    Description

    给定一张无向图,求两点之间次短路的长度

    Solution

    关于用A*算法求解k短路,在此不再赘述,相关内容请见这里

    这里主要讲述一个坑点,本题是无向图(与POJ2449不同),我们在A*扩展节点时需要标记该节点是否已经在当前这条路径上,否则,我们求出的次短路是不正确的,排除这个问题,剩下的就是简单的A*了。

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct Node {
     4     double x, y;
     5 } node[210];
     6 int n, m;
     7 double dis[210];
     8 struct Edge {
     9     int next, to;
    10     double dis;
    11 } a[50010 << 1];
    12 int num, head[50010];
    13 struct Dijkstra {
    14     int id;
    15     double dis;
    16     bool operator <(const Dijkstra &x) const {
    17         return dis > x.dis;
    18     }
    19 };
    20 priority_queue <Dijkstra> h;
    21 int vis[210];
    22 struct A_star {
    23     int id;
    24     double dis, val;
    25     int pd[210];
    26     bool operator <(const A_star &x) const {
    27         return dis + val > x.dis + x.val;
    28     }
    29 };
    30 priority_queue <A_star> q;
    31 inline double dist(double x, double y, double x0, double y0) {
    32     return sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0));
    33 }
    34 inline void add(int from, int to, double dis) {
    35     a[++num].next = head[from];
    36     a[num].to = to;
    37     a[num].dis = dis;
    38     head[from] = num;
    39 }
    40 int main() {
    41     scanf("%d%d", &n, &m);
    42     for (register int i = 1; i <= n; ++i) scanf("%lf%lf", &node[i].x, &node[i].y);
    43     for (register int i = 1; i <= m; ++i) {
    44         int x, y;
    45         scanf("%d%d", &x, &y);
    46         add(x, y, dist(node[x].x, node[x].y, node[y].x, node[y].y));
    47         add(y, x, dist(node[x].x, node[x].y, node[y].x, node[y].y));
    48     } 
    49     for (register int i = 1; i <= n; ++i) dis[i] = 1e9;
    50     dis[n] = 0;
    51     h.push((Dijkstra){n, 0});
    52     while (!h.empty()) {
    53         int now = h.top().id;
    54         h.pop();
    55         if (vis[now]) continue ;
    56         vis[now] = 1;
    57         for (register int i = head[now]; i; i = a[i].next)
    58             if (dis[a[i].to] > dis[now] + a[i].dis) {
    59                 dis[a[i].to] = dis[now] + a[i].dis;
    60                 h.push((Dijkstra){a[i].to, dis[a[i].to]});
    61             }
    62     }
    63     memset(vis, 0, sizeof(vis));
    64     q.push((A_star){1, dis[1], 0});
    65     while (!q.empty()) {
    66         A_star now = q.top();
    67         q.pop();
    68         vis[now.id]++;
    69         if (vis[now.id] > 2) continue ;
    70         if (vis[now.id] == 2 && now.id == n) {
    71             printf("%.2lf
    ", now.val);
    72             return 0;
    73         }
    74         for (register int i = head[now.id]; i; i = a[i].next) {
    75             A_star neww;
    76             if (now.pd[a[i].to]) continue ;
    77             neww = now;
    78             neww.pd[a[i].to] = 1;
    79             neww.id = a[i].to;
    80             neww.dis = dis[neww.id];
    81             neww.val = now.val + a[i].dis;
    82             q.push(neww);
    83         }
    84     }
    85     puts("-1");
    86     return 0;
    87 }
    AC Code
  • 相关阅读:
    echarts动态设置主体颜色
    spring security session
    Spark RDD函数:
    MapReduce TOP n
    feign 使用示例
    trie树
    动态修改注解(annotation)值
    golang插件
    Kafka Streams Example
    tcp并发(c18w)
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11199212.html
Copyright © 2011-2022 走看看