• 第K短路(模板)


     没太想明白(就当存在模板吧)

    #include<bits/stdc++.h>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <stack>
    #include <vector>
    using namespace std;
    typedef long long LL;
    const int Maxn = 1e5 + 7;
    const int Inf = 1e9 + 7;
    int N, M, K;
    int start, End;
    int ans;
    //最短路部分
    int dis[Maxn];
    bool vis[Maxn];
    struct node
    {
        int v, w;
        friend bool operator < (node a, node b)
        {
            return a.w > b.w;
        }
    };
    
    /*
     * A* 启发式搜索函数 F[x] = H[x] + G[x]
     * 变量 Hx 表示搜索到当前点 所用的代价
     * 变量 Gx 是估价函数 (估价函数要小于等于实际值,否则出错)
     */
    struct edge
    {
        int v, Hx, Gx;
        friend bool operator < (edge a, edge b)
        {
            return a.Hx + a.Gx > b.Hx + b.Gx;
        }
    };
    /*
     * count 记录第几次BFS拓展到此点
     * 当 count == K 时  不再对此点继续进行拓展(因为拓展的点必定大于 第K短路)
     */
    int Count[Maxn];
    vector <node> G[Maxn], G2[Maxn];
    
    /*
     * (因为是有向图所以反向建图)
     * 求End到每个点的最短路
     */
    void Dijkstra()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,Inf,sizeof(dis));
        priority_queue <node> que;
        que.push({End, 0});
        dis[End] = 0;
        node q;
        int v, w;
        while(!que.empty()){
            int v = que.top().v;
            que.pop();
            if(vis[v])
                continue;
            vis[v] = true;
            int _size=G2[v].size();
            for(int i = 0 ; i < _size ; i++){
                node now=G2[v][i];
                if(dis[now.v] > dis[v]+now.w){
                    dis[now.v] = dis[v]+now.w;
                  que.push({now.v,dis[now.v]});
                }
            }
        }
    }
    /*
     * 第K短路算法 = A* + BFS
     */
    void Astar(){
        ans = -1;
        memset(Count,0,sizeof(Count));
        priority_queue <edge> que;
        que.push({start, 0, 0});
        edge q;
        int v, Hx, Gx;
        while(!que.empty()){
            q = que.top();
            que.pop();
            v = q.v, Hx = q.Hx, Gx = q.Gx;
            Count[v]++;
            if(Count[v] == K && v == End){
                ans = Hx + Gx;
                break;
            }
            if(Count[v] > K)
                continue;
            int to, hx, gx;
            int _size=G[v].size();
            for(int i = 0 ; i < _size ; i++)
            {
                to = G[v][i].v;
                hx = Hx + G[v][i].w;
                gx = dis[to];
                que.push({to, hx,gx});
            }
        }
        while(!que.empty())
            que.pop();
        return;
    }
    int main(){
        while(~scanf(" %d %d",&N,&M)){
            for(int i = 1 ; i <= N ; i++)
                G[i].clear();
            for(int i = 1 ; i <= M ; i++){
                int u, v, w;
                scanf("%d%d%d",&u,&v,&w);
                G[u].push_back({v, w});
                G2[v].push_back({u, w});
            }
            scanf(" %d %d %d",&start, &End, &K);
            //此题要求start和End相同的时候 第一短路不是0 ,所以K++
            if(start == End)
                K++;
                Dijkstra();
                Astar();
                printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    1 1
    2 2 5
    2 2 1*/
    View Code
  • 相关阅读:
    Linux下防火墙的相关命令
    java中的异常总结
    Java中的==和equals的区别
    一个简单的前后端分离项目,适合新手练手
    入住博客园鸭
    centos7 安装 Python PIL模块
    Linux 装机错误解决
    Python 爬取煎蛋网妹子图片代码
    Python 简易聊天机器人
    Python员工信息表练习
  • 原文地址:https://www.cnblogs.com/sszywq/p/13933806.html
Copyright © 2020-2023  润新知