【洛谷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\n", 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

 

posted @ 2019-07-17 10:11  AD_shl  阅读(241)  评论(0编辑  收藏  举报