zoukankan      html  css  js  c++  java
  • aStar算法求第k短路

    A*的概念主意在于估计函数,f(n)=g(n)+h(n),f(n)是估计函数,g(n)是n节点的当前代价,h(n)是n节点的估计代价;而实际中,存在最优的估计函数f'(n)=g'(n)+h'(n),那么显然我们在A*的估计中,h(n)<=h'(n),否则你将搜不到最优解;(g(n)>=g'(n)我还不怎么清楚为什么啊,大多数情况是g(n)=g'(n),这个可以不用管吧。。)

    求s->t的第k短路,

    dist[x]为x->t的最短路 (这个只要反向建边,然后一次spfa,求出任意点到t点的距离即可

    那么点x的g(x)=到达当前点的花费

    h(x) = dist[x] ,    可以知道h(x)=h'(x),所以可以保证搜到最优解。

    每次出出队列的都是当前f(x)最小的点,

    所以如果点x出队列, 那么就cnt[x]++,

    当cnt[x]==k时,那么当前的f(x)就是第k短路,因为第一次出队列时,肯定是最短路上的点,第二次是次短路上的点,第k次,自然就是第k短路上的点了。

      1 #pragma warning(disable:4996)
      2 #pragma comment(linker, "/STACK:1024000000,1024000000")
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <time.h>
      6 #include <math.h>
      7 #include <map>
      8 #include <set>
      9 #include <queue>
     10 #include <stack>
     11 #include <vector>
     12 #include <bitset>
     13 #include <algorithm>
     14 #include <iostream>
     15 #include <string>
     16 #include <functional>
     17 #include <iostream>
     18 typedef __int64 LL;
     19 const int INF = 1 << 30;
     20 
     21 /*
     22 */
     23 const int N = 1000 + 10;
     24 struct Node
     25 {
     26     int from, to, dis, next;
     27 }g[N*100];
     28 int head[N], e;
     29 int dist[N];
     30 bool vis[N];
     31 int cnt[N];
     32 void addEdge(int u, int v, int dis)
     33 {
     34     g[e].from = u;
     35     g[e].to = v;
     36     g[e].dis = dis;
     37     g[e].next = head[u];
     38     head[u] = e++;
     39 }
     40 
     41 void spfa(int src, int n)
     42 {
     43     for (int i = 1;i <= n;++i)
     44         dist[i] = INF;
     45     std::queue<int> q;
     46     q.push(src);
     47     dist[src] = 0;
     48     while (!q.empty())
     49     {
     50         int u = q.front(); q.pop();
     51         vis[u] = false;
     52         for (int i = head[u];i + 1;i = g[i].next)
     53         {
     54             int v = g[i].to;
     55             if (dist[v] > dist[u] + g[i].dis)
     56             {
     57                 dist[v] = dist[u] + g[i].dis;
     58                 if (!vis[v])
     59                 {
     60                     vis[v] = true;
     61                     q.push(v);
     62                 }
     63             }
     64         }
     65     }
     66 }
     67 void init()
     68 {
     69     e = 0;
     70     memset(head, -1, sizeof(head));
     71 }
     72 void reverse()
     73 {
     74     memset(head, -1, sizeof(head));
     75     int te = e;
     76     e = 0;
     77     for (int i = 0;i < te;++i)
     78         addEdge(g[i].to, g[i].from, g[i].dis);
     79 }
     80 struct Node2
     81 {
     82     int to;
     83     int g;
     84     bool operator<(const Node2&rhs)const
     85     {
     86         return g + dist[to] > rhs.g + dist[rhs.to];
     87     }
     88 };
     89 /*
     90 因为每次出队列的都是最短的, 所以该点是第几次出队列,就表示是该点到终点的第k短路
     91 */
     92 int aStar(int src, int des, int k)
     93 {
     94     std::priority_queue<Node2> q;
     95     Node2 cur, tmp;
     96     cur.to = src;
     97     cur.g = 0;
     98     q.push(cur);
     99     while (!q.empty())
    100     {
    101         cur = q.top(); q.pop();
    102         int u = cur.to;
    103         cnt[u]++;
    104         if (cnt[u] > k) continue;
    105         if (cnt[u] == k)
    106             return cur.g + dist[u];
    107         for (int i = head[u];i + 1;i = g[i].next)
    108         {
    109             int v = g[i].to;
    110             tmp.to = v;
    111             tmp.g = cur.g + g[i].dis;
    112             q.push(tmp);
    113         }
    114     }
    115     return -1;
    116 }
    117 int main()
    118 {    
    119     int n, m, src, des, k;
    120     while (scanf("%d%d", &n, &m) != EOF)
    121     {
    122         init();
    123         int u, v, dis;
    124         for (int i = 1;i <= m;++i)
    125         {
    126             scanf("%d%d%d", &u, &v, &dis);
    127             addEdge(v, u, dis);
    128         }
    129         scanf("%d%d%d", &src, &des, &k);
    130         spfa(des, n);
    131         reverse();
    132         if (src == des)k++;//如果起点等于终点,那么最短路其实是什么都不走
    133         int ans = aStar(src, des, k);
    134         printf("%d
    ", ans);
    135     }
    136     return 0;
    137 }
    View Code
  • 相关阅读:
    网站常见的反爬虫和应对方法 + [评论]
    斯坦福大学自然语言处理第一课——引言(Introduction)
    爬虫入门实战,知乎小爬虫
    使用情感分析技术做营销
    字符串匹配的KMP算法
    向Array中添加希尔排序
    向Array中添加二分插入排序
    向Array中添加插入排序
    开辟我的前端之旅!
    【apache】yum 安装Apache(Centos 6.5)
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4789730.html
Copyright © 2011-2022 走看看