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

  题目链接

  K短路居然用A*……奇妙。

  先建反图从终点(1)跑一遍最短路,再A*,用堆存当前点到终点距离+从起点到当前点距离。

  每次取出终点都可以视为发现了一个新的最短路。

  

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
#define maxn 1020
#define maxm 10020
using namespace std;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch==‘-‘)    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-‘0‘;
        ch=getchar();
    }
    return num*f;
}

struct Node{
    int pnt,dis;
    bool operator <(const Node a)const{
        return dis<a.dis;
    }
    bool operator ==(const Node a)const{
        return dis==a.dis;
    }
    bool operator <=(const Node a)const{
        return dis<=a.dis;
    }
};

struct Heap{
    Node heap[maxn*100];
    int size;
    Heap(){size=0;}
    inline void push(Node x){
        heap[++size]=x;
        register int i=size,k;
        while(i>1){
            k=i>>1;
            if(heap[k]<=heap[i])    return;
            swap(heap[k],heap[i]);
            i=k;
        }
    }
    inline Node pop(){
        Node ans=heap[1];    heap[1]=heap[size--];
        register int i=1,k;
        while((i<<1)<=size){
            k=i<<1;
            if(k<size&&heap[k|1]<heap[k])    k|=1;
            if(heap[i]<=heap[k])    return ans;
            swap(heap[k],heap[i]);
            i=k;
        }
        return ans;
    }
}s;

int ans[maxn],cnt;
int dis[maxn];
bool vis[maxn];

struct Picture{
    struct Edge{
        int next,to,val;
    }edge[maxm*2];
    int head[maxn],num;
    Picture(){memset(vis,0,sizeof(vis));num=0;memset(head,0,sizeof(head));}
    inline void add(int from,int to,int val){
        edge[++num]=(Edge){head[from],to,val};
        head[from]=num;
    }
    void prepare(int Start){
        memset(dis,127/3,sizeof(dis));    dis[Start]=0;
        queue<int>q;    q.push(Start);
        while(!q.empty()){
            int from=q.front();q.pop();
            vis[from]=0;
            for(int i=head[from];i;i=edge[i].next){
                int to=edge[i].to;
                if(dis[to]<=dis[from]+edge[i].val)    continue;
                dis[to]=dis[from]+edge[i].val;
                if(vis[to])    continue;
                vis[to]=1;    q.push(to);
            }
        }
        return;
    }
    void Astar(int Start,int tme){
        s.push((Node){Start,dis[Start]});
        while(s.size){
            Node from=s.pop();
            int x=from.pnt,dst=from.dis;
            if(x==1)    ans[++cnt]=dst;
            if(tme==cnt)    return;
            for(int i=head[x];i;i=edge[i].next){
                int to=edge[i].to;
                s.push((Node){to,dst-dis[x]+edge[i].val+dis[to]});
            }
        }
    }
}Pre,Sub;

int main(){
    memset(ans,-1,sizeof(ans));
    int n=read(),m=read(),e=read();
    for(int i=1;i<=m;++i){
        int x=read(),y=read(),z=read();
        if(x<y)    swap(x,y);
        Pre.add(x,y,z);
        Sub.add(y,x,z);
    }
    Sub.prepare(1);
    Pre.Astar(n,e);
    for(int i=1;i<=e;++i)    printf("%d\n",ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/cellular-automaton/p/8379540.html

时间: 2024-11-05 20:38:07

【Luogu】P2901牛慢跑(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

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

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

[USACO Mar08] 牛跑步 --k短路

[USACO Mar08] 牛跑步 Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚. Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<=1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是Bessie的牛棚;地点1是池塘. 很快, Bessie厌倦了一直走同一条路.所以她想走不同的路,更明确地讲

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

洛谷 [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

[K短路] SDOI2010 魔法猪学院

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