POJ-2449 最短路+A*求K短路 模板

题意:有向图求S到T的第K短路

说下A*,其实这只是个辅助功能,通俗点不说估值函数什么的其实很容易理解,就是个搜索方式

如果我们放很多个速度一样的人在起点,随便他们怎么走,那我们在终点等到的第K个人走的路,肯定就是第K短路

那么我们随意放人得到所有路径长度,就是爆搜,爆搜肯定会超时

这时候我们就需要一个优化,先从当前最短路的那个节点开始扩展,再从第二、第三……这样可以在获得第K短路的时候就返回了,而且也不会在这之前走一条“绕了半个世界”的超长路,这个“最短优先”在这里用优先队列实现。说回A*算法本身,“选择原则”就是取出花费最小的,估值函数在这里就是走一条边的花费,换到别的问题下面就是到下一状态的花费

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<queue>
 6 #define INF 0x3f3f3f3f
 7 #define LL long long
 8 #define debug(x) cout << "[" << x << "]" << endl
 9 using namespace std;
10 
11 const int mx = 1e5+10;
12 
13 struct node{
14     int id, f, g;
15     node(int id = 0, int f = 0, int g = 0): id(id), f(f), g(g){}
16     bool operator < (const node& a) const {
17         return a.f < f || (a.f == f && a.g < g);
18     }
19 };
20 
21 struct edge{
22     int v, w, next;
23 }e[mx], e2[mx];
24 int h[1010], h2[1010], d[1010];
25 bool vis[1010];
26 int cnt = 1, k;
27 
28 void add(int u, int v, int w){
29     e[cnt].v = v;
30     e[cnt].w = w;
31     e[cnt].next = h[u];
32     h[u] = cnt;
33     e2[cnt].v = u;
34     e2[cnt].w = w;
35     e2[cnt].next = h2[v];
36     h2[v] = cnt;
37     cnt++;
38 }
39 
40 void spfa(int s){
41     queue<int> q;
42     memset(d, INF, sizeof d);
43     d[s] = 0;
44     vis[s] = 1;
45     q.push(s);
46     while (!q.empty()){
47         int u = q.front(); q.pop();
48         vis[u] = 0;
49         for (int i = h2[u]; i; i = e2[i].next){
50             int v = e2[i].v, w = e2[i].w;
51             if (d[v] > d[u]+w){
52                 d[v] = d[u]+w;
53                 if (vis[v]) continue;
54                 vis[v] = 1;
55                 q.push(v);
56             }
57         }
58     }
59 }
60 
61 void Astar(int s, int t){
62     if (s == t) k++;
63     priority_queue<node> q;
64     q.push(node(s, 0, 0));
65     int ans = 0;
66     while (!q.empty()){
67         node u = q.top(); q.pop();
68         if (u.id == t && ++ans == k){
69             printf("%d\n", u.f);
70             return;
71         }
72         for (int i = h[u.id]; i; i = e[i].next){
73             int v = e[i].v;
74             q.push(node(v, u.g + d[v] + e[i].w, u.g + e[i].w));
75         }
76     }
77     printf("-1\n");
78 }
79 
80 int main(){
81     int n, m, u, v, w, s, t;
82     scanf("%d%d", &n, &m);
83     for (int i = 0; i < m; i++){
84         scanf("%d%d%d", &u, &v, &w);
85         add(u, v, w);
86     }
87     scanf("%d%d%d", &s, &t, &k);
88     spfa(t);
89     Astar(s, t);
90     return 0;
91 }

 

posted @ 2018-08-03 16:13  QAQorz  阅读(442)  评论(0编辑  收藏  举报