第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\n",ans);
    }
    return 0;
}
/*
1 1
2 2 5
2 2 1*/
View Code

 

posted @ 2020-11-05 20:33  Swelsh-corgi  阅读(69)  评论(0编辑  收藏  举报