zoukankan      html  css  js  c++  java
  • POJ2449-A*算法-第k短路

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

    题意:传送门

     原题目描述在最下面。
     给你一个有向图,求指定节点间的第k短路。

    思路:

     先反向跑出从终点开始的到每个节点的最短距离。
     乐观估计函数(f(n) = g(n) + h'(n))(g(n))表示到当前状态跑的距离,(h'(n))表示到目标状态还需要的距离。
     对于(A*)然后跑一遍(bfs)就可以了。

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<assert.h>
    #include<bitset>
    #include<vector>
    #include<queue>
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) (x)&(-(x))
    #define all(x) (x).begin(),(x).end()
    #define mk make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int N = (int)1e3 +107;
    int n, m, k, st, ed;
    int dis[N],vis[N],time[N];
    struct lp{
      int f,g,v;
      friend bool operator <(const lp &a,const lp &b){
        if(a.f==b.f)return a.g>b.g;
        return a.f>b.f;
      }
    }aa,bb;
    struct lh{
      int v,w,nex;
    }cw[100000+5],rev[100000+5];
    int head[N],tot,headd[N],tum;
    int q[2500005];
    void add(int u,int v,int w){
      cw[++tot].v=v;cw[tot].nex=head[u];cw[tot].w=w;
      head[u]=tot;
    
      rev[++tum].v=u;rev[tum].nex=headd[v];rev[tum].w=w;
      headd[v]=tum;
    }
    void spfa(){
      for(int i = 1; i <= n; i++) dis[i] = INF;
      memset(vis, 0, sizeof(vis));
      int h = 0, t = 1;
      q[0] = ed;
      dis[ed] = 0;
      while(h < t){
        int u = q[h++];
        vis[u] = 0;
        for(int i = headd[u] ; ~i ; i = rev[i].nex){
          int v = rev[i].v, w = rev[i].w;
          if(dis[v] > dis[u] + w){
            dis[v] = dis[u] + w;
            if(!vis[v]){
              q[t++] = v;
              vis[v] = 1;
            }
          }
        }
      }
    }
    int Astar(){
      if(dis[st]==INF)return -1;
      memset(time,0,sizeof(time));
      aa.v=st;aa.f=dis[st];aa.g=0;
      priority_queue<lp>Q;
      Q.push(aa);
      while(!Q.empty()){
        bb = Q.top();Q.pop();
        int u = bb.v;
        time[u]++;
        if(time[u]==k&&u==ed)return bb.g;
        if(time[u]>k)continue;
        for(int i=head[u];~i;i=cw[i].nex){
          int v = cw[i].v;
          aa.v = v;
          aa.g=bb.g+cw[i].w;
          aa.f=aa.g+dis[v];
          Q.push(aa);
        }
      }
      return -1;
    }
    int main(){
      while(~scanf("%d%d", &n, &m)){
        tot=tum=-1;
        memset(head,-1,sizeof(head));
        memset(headd,-1,sizeof(headd));
        for(int i = 0, u, v, w; i < m; ++i){
          scanf("%d%d%d", &u, &v, &w);
          add(u,v,w);
        }
        scanf("%d%d%d", &st, &ed, &k);
        spfa();
        if(st == ed)k++;
        printf("%d
    ", Astar());
      }
      return 0;
    }
    

    ####原题目描述:
  • 相关阅读:
    一天一个shell实例(1)文本中n个出现频率最高的单词(转)
    JNDI全攻略(一)(转)
    JNDI 学习(转)
    JNDI全攻略(二)(转)
    C#开发系列 文章索引
    AppControls
    JSF系列 文章索引
    [转载]DELPHI组件安装全攻略
    什么是有价值的人生
    [转载]InnoSetup5.2.3啊风增强版 安装代码
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/9513214.html
Copyright © 2011-2022 走看看