【洛谷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 }