zoukankan      html  css  js  c++  java
  • 【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
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    codeforces 765 F Souvenirs 线段树+set
    codeforces 768 E 变形NIM博弈/手写sg函数
    BZOJ 1001 狼抓兔子(网络流)
    BZOJ 2957 楼房重建 (分块)
    CodeForces
    CodeForces
    HYSBZ
    SPOJ
    Codeforces-963 D Frequency of String
    中石油2019寒假集训第一场(新生场)(补题)
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8379540.html
Copyright © 2011-2022 走看看