zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ");
    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 }
  • 相关阅读:
    判断页面访问端是电脑还是手机?
    Vue使用总结
    JS面向对象,创建,继承
    你不得不知的逻辑或(||)与(&&)非(!)
    前端必备PS技巧
    你真的熟悉background吗?
    JS运动从入门到兴奋1
    过目不忘JS正则表达式
    W3C、MDN及html常用标签介绍
    js数据处理-----数据拷贝
  • 原文地址:https://www.cnblogs.com/QAQorz/p/9414758.html
Copyright © 2011-2022 走看看