zoukankan      html  css  js  c++  java
  • 【模板】K短路 A-star

    引理:当一个状态对应的节点第K次从堆中取出时,该状态对应的当前代价是从起点到该点的第K优解。

    代码如下

    /*
        POJ2449
    */
    #include <cstdio>
    #include <iostream>
    #include <memory.h>
    #include <queue>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int maxv=1010;
    const int maxe=1e5+10;
    
    inline int read(){
        int x=0,f=1;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
        do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
        return f*x;
    }
    
    struct edge{
        int nxt,to,w;
        edge(int x=0,int y=0,int z=0):nxt(x),to(y),w(z){}
    }e[maxe],_e[maxe];
    int tot=1,head[maxv],_tot=1,_head[maxv];
    
    inline void add_edge(int from,int to,int w){
        e[++tot]=edge(head[from],to,w),head[from]=tot;
        _e[++_tot]=edge(_head[to],from,w),_head[to]=_tot;
    }
    
    int n,m,st,ed,k,d[maxv],cnt[maxv];
    bool vis[maxv];
    
    typedef pair<int,int> P;
    
    void dij(){
        priority_queue<P> q;
        memset(d,0x3f,sizeof(d));
        d[ed]=0;q.push(make_pair(0,ed));
        while(q.size()){
            int u=q.top().second;q.pop();
            if(vis[u])continue;
            vis[u]=1;
            for(int i=_head[u];i;i=_e[i].nxt){
                int v=_e[i].to,w=_e[i].w;
                if(d[v]>d[u]+w){
                    d[v]=d[u]+w;
                    q.push(make_pair(-d[v],v));
                }
            }
        }
    }
    
    void read_and_parse(){
        n=read(),m=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),z=read();
            add_edge(x,y,z);
        }
        st=read(),ed=read(),k=read();
        if(st==ed)k++;
        dij();
    }
    
    struct node{//状态
        int idx,now,fur;
        node(int x=0,int y=0,int z=0):idx(x),now(y),fur(z){}
        friend bool operator<(const node& a,const node& b){
            return b.now+b.fur<a.now+a.fur;
        }
    };
    
    int solve(){
        priority_queue<node> q;
        q.push(node(st,0,d[st]));
        while(q.size()){
            node u=q.top();++cnt[u.idx];q.pop();
            if(cnt[u.idx]==k&&u.idx==ed)return u.now;
            if(cnt[u.idx]>k)continue;//如果当前节点出队次数大于K,则跳过
            for(int i=head[u.idx];i;i=e[i].nxt){
                int v=e[i].to,w=e[i].w;
                q.push(node(v,u.now+w,d[v]));
            }
        }
        return -1;
    }
    
    int main(){
        read_and_parse();
        printf("%d
    ",solve());
        return 0;
    }
    
  • 相关阅读:
    SpringCloud-sleuth-zipkin链路追踪
    关于encodeURI() 踩的坑
    兄弟ifream的方法调用
    jq为什么能用$操作
    js获取一周的日期范围
    layui中实现上传图片压缩
    input预览上传图片
    js获取地址栏参数
    计算两天之间的天数差
    文字始终均匀分布整个div
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9814021.html
Copyright © 2011-2022 走看看