• A*算法


    A*算法中最关键肯定是f=g+h。估价函数h,代价函数g。

    每次取出f最小的,然后开始更新周围的节点。

    对于未到达的节点直接更新,已到达的节点用g值比较一下,更优则更新。

    而估价函数在一开始就算好了。

    那么对于k短路问题呢。

    首先预处理出终点t到每个点的最短路,即为估价函数h。(最常用的做法)

    然后从起点出发,代价什么的走的时候算一下就好了。

    于是当经过一个节点k次的时候就是该节点的第k短路。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=100005;
    const int inf=1e9;
    struct Edge{
        int to,next,v;
    }g[maxn],gt[maxn];
    int head[1005],headt[1005],cnt,cntt;
    void addedge(int u,int v,int w)
    {
        g[++cnt]=(Edge){v,head[u],w};
        head[u]=cnt;
        gt[++cntt]=(Edge){u,headt[v],w};
        headt[v]=cntt;
    }
    struct Dijnode
    {
        int x,d;
        Dijnode(int a,int b):x(a),d(b){}
        bool operator < (const Dijnode &a) const{
            return d>a.d;
        }
    };
    int dis[1005];
    bool vis[1005];
    void dijkstra(int s){
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;
        priority_queue<Dijnode>q;
        q.push(Dijnode(s,0));
        while(!q.empty()){
            Dijnode x=q.top();
            q.pop();
            int u=x.x;
            if(vis[u])
                continue;
            vis[u]=true;
            for(int i=headt[u];i;i=gt[i].next){
                int v=gt[i].to;
                if(dis[v]>dis[u]+gt[i].v){
                    dis[v]=dis[u]+gt[i].v;
                    q.push(Dijnode(v,dis[v]));
                }
            }
        }
    }
    struct Anode
    {
        int f,g,v;
        Anode(int a,int b,int c):f(a),g(b),v(c){}
        bool operator < (const Anode &a) const{
            return f>a.f;
        }
    };
    int inq[1005];
    int A_star(int s,int t,int k){
        priority_queue<Anode>q;
        if(dis[s]>inf)
            return -1;
        memset(inq,0,sizeof(inq));
        q.push(Anode(dis[s],0,s));
        while(!q.empty()){
            Anode x=q.top();
            q.pop();
            int u=x.v;
            inq[u]++;
            if(inq[t]==k)
                return x.f;
            if(inq[u]>k)
                continue;
            for(int i=head[u];i;i=g[i].next){
                int v=g[i].to,w=g[i].v;
                q.push(Anode(dis[v]+w+x.g,x.g+w,v));
            }
        }
        return -1;
    }
    template<class T>void read(T &x){
        static char c;
        static bool f;
        for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1;
        for(x=0;isdigit(c);c=getchar())x=x*10+c-'0';
        if(f)x=-x;
    }
    int main(){
        int n,m;read(n);read(m);
        int u,v,w;
        for(int i=1;i<=m;i++){
            read(u);read(v);read(w);
            addedge(u,v,w);
        }
        int s,t,k;read(s);read(t);read(k);
        dijkstra(t);
        if(s==t)k++;
        printf("%d",A_star(s,t,k));
        return 0;
    }

    短路了。

  • 相关阅读:
    document基本操作 动态脚本-动态样式-创建表格
    js原型模式和继承
    NuGet本地包自定义路径
    技术文档链接收藏
    数据结构排序
    Insertion Sort
    选择排序之javascript
    冒泡排序之javascript
    C++双向链表
    单向链表
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/5917319.html
Copyright © 2020-2023  润新知