K短路【模板】

A*+SPFA算法:

(1)将有向图的所有边正向、反向分别存入两个不同的边集(Edges,Edges1)中。用反向边集,以所求终点t为源点,利用SPFA或Dijkstra求解出所有点到t的最短路径,用Dist[i]数组来表示点i到点t的最短距离。

(2)建立一个优先队列,将源点s加入到队列中。

(3)从优先队列中取出最小的点p,如果点p == t,则计算t出队的次数。如果当前路径长度就是s到t的第k短路长度,算法结束。否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先队列中取。

注意:

当s == t的时候,需要计算第k+1短路。因为s到t这条距离为0的路不能算是这k短路里边,当s == t的时候,只需要将k = k+1后再求第k短路就可以了。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 1100;
const int MAXM = 110000;
const int INF = 0xffffff0;

struct EdgeNode
{
    int to;
    int w;
    int next;
}Edges[MAXM],Edges1[MAXM];

int Head[MAXN],Head1[MAXN];

struct Node
{
    int to;
    int g,f;
    bool operator < (const Node &r) const
    {
        if(r.f == f)
            return r.g < g;
        return r.f < f;
    }
};
int vis[MAXN],Dist[MAXN];

int A_Star(int start,int end,int N,int k)
{
    Node e,ne;
    int Cnt = 0;
    priority_queue<Node> que;
    if(start == end)
        k++;
    if(Dist[start] == INF)
        return -1;
    e.to = start;
    e.g = 0;
    e.f = e.g + Dist[e.to];
    que.push(e);
    while( !que.empty() )
    {
        e = que.top();
        que.pop();
        if(e.to == end)
            Cnt++;
        if(Cnt == k)
            return e.g;

        for(int i = Head[e.to]; i != -1; i = Edges[i].next)
        {
            ne.to = Edges[i].to;
            ne.g = e.g + Edges[i].w;
            ne.f = ne.g + Dist[ne.to];
            que.push(ne);
        }
    }
    return -1;
}
void SPFA(int s,int N)
{
    for(int i = 0; i <= N; ++i)
        Dist[i] = INF;
    memset(vis,0,sizeof(vis));
    vis[s] = 1;
    Dist[s] = 0;
    queue<int> Q;
    Q.push(s);
    while( !Q.empty() )
    {
        int u = Q.front();
        Q.pop();
        vis[u] = 0;
        for(int i = Head1[u]; i != -1; i = Edges1[i].next)
        {
            int temp = Dist[u] + Edges1[i].w;
            if(temp < Dist[Edges1[i].to])
            {
                Dist[Edges1[i].to] = temp;
                if(!vis[Edges1[i].to])
                {
                    vis[Edges1[i].to] = 1;
                    Q.push(Edges1[i].to);
                }
            }
        }
    }
}

int main()
{
    int N,M,u,v,w,s,t,k;
    while(~scanf("%d%d",&N,&M))
    {
        memset(Edges,0,sizeof(Edges));
        memset(Edges1,0,sizeof(Edges1));
        memset(Head,-1,sizeof(Head));
        memset(Head1,-1,sizeof(Head1));
        for(int i = 0; i < M; ++i)
        {
            scanf("%d%d%d",&u,&v,&w);
            Edges[i].to = v;
            Edges[i].w = w;
            Edges[i].next = Head[u];
            Head[u] = i;

            Edges1[i].to = u;
            Edges1[i].w = w;
            Edges1[i].next = Head1[v];
            Head1[v] = i;
        }
        scanf("%d%d%d",&s,&t,&k);
        SPFA(t,N);
        int kthlenth = A_Star(s,t,N,k);
        printf("%d\n",kthlenth);
    }

    return 0;
}
时间: 2024-12-25 18:01:05

K短路【模板】的相关文章

POJ 2449Remmarguts&#39; Date K短路模板 A*+SPFA

太水了我不想说了,模板在这里 14312K 313MS 1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int v[100010],v2[100010],c[100010],c2[100010],s,t,k,duin; 7 int n,m,point[1010],next[100010],cnt=0,

poj 2449 Remmarguts&#39; Date (k短路模板)

Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30772   Accepted: 8397 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly tou

POJ 2449 Remmarguts&#39; Date(k短路模板)

link:https://vjudge.net/problem/POJ-2449 前面输入与大多最短路题相同 最后一行输入s,t,k 求从s到t的第K短路 #include <iostream> #include <cstring> #include <queue> using namespace std; const int MAXN=1010; struct node { int p,g,h; bool operator < (node a) const {

[poj2449]Remmarguts&#39; Date(K短路模板题,A*算法)

解题关键:k短路模板题,A*算法解决. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=1e3+10; const

【Luogu】P2901牛慢跑(K短路模板)

题目链接 K短路居然用A*……奇妙. 先建反图从终点(1)跑一遍最短路,再A*,用堆存当前点到终点距离+从起点到当前点距离. 每次取出终点都可以视为发现了一个新的最短路. #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cctype> #include<queue> #define maxn 1020 #define m

A*算法的认识与求第K短路模板

现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎么求呢? 对于第k短路,可以想到的一个比较朴素的算法就是广度优先搜索,使用优先队列从源点s进行广搜,当第k次搜索到终点t时,所的长度即所求但是这种方法在运行过程中会产生特别多的状态,当图比较简单.k比较小时,可以一试,但是当k较大或者图中点数较多时,会面临爆栈的危险.目前使用比较多的算法是单源最短路

洛谷 [P2483] [模板] k短路

人生中的第一道黑题... 其实就是k短路模板 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #include <queue> using namespace std; const int MAXN=400005; int init(){ int

bzoj 1598: [Usaco2008 Mar]牛跑步 -- 第k短路,A*

1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MB Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. BESSIE也不想跑得太远,所以她想走最短的路经. 农场上一共有M (1 <= M <= 10,000)条路, 每条路连接两个用1..N(1 <= N <= 1000)标号的地点. 更方便的是,如果X>Y,则地点X

[K短路] SDOI2010 魔法猪学院

魔法猪学院 题目背景 感谢@kczno1 @X_o_r 提供hack数据 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与元素之间可以互相转换:能量守恒--. 能量守恒--iPig 今天就在进行一个麻烦的测验.iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量.作为 PKU 的顶尖

POJ 2449 Remmarguts&#39; Date (第k短路 A*搜索算法模板)

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 22412   Accepted: 6085 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h