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 }