zoukankan      html  css  js  c++  java
  • 【洛谷P4568】[JLOI2011]飞行路线

    飞行路线

    题目链接

    今天上午模拟考试考了原题,然而数组开小了,爆了4个点。

    据王♂强dalao说这是一道分层图SPFA的裸题

    dis[i][j]表示到点i用k个医疗包的最小消耗,dis[u][j]+e[i].w更新dis[v][j],

    dis[u][j]更新dis[v][j+1]

    然而它卡SPFA,会TLE几个点

    于是就有了堆优化SPFA。。(它就是堆优化dijkstra。。)

    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define INF 0x3f3f3f3f
    #define N 10010
    int n,m,k,s,t,ans=INF;
    int dis[N][12];
    struct HA{
        int pos,cost,times;
    };
    struct cmp{
        bool operator()(HA x,HA y){
            return x.cost==y.cost?x.times>y.times:x.cost>y.cost;
        }
    };
    std::priority_queue< HA, std::vector<HA>, cmp > q;
    bool vis[N][12];
    int Head[N],num;
    struct NODE{
        int to,w,next;
    } e[100010];
    const int ch_top=4e7+3;
    char ch[ch_top],*now_r=ch-1,*now_w=ch-1;
    inline int read(){
        while(*++now_r<'0');
        register int x=*now_r-'0';
        while(*++now_r>='0')x=x*10+*now_r-'0';
        return x;
    }
    inline void write(int x){
        static char st[20];static int top;
        while(st[++top]='0'+x%10,x/=10);
        while(*++now_w=st[top],--top);
        *++now_w='
    ';
    }
    void SPFA(){
        memset(dis,0x3f,sizeof(dis));
        for(int i=0;i<=k;i++){
            dis[s][i]=0;
            q.push((HA){s,0,i});
        }
        while(!q.empty()){
            int u=q.top().pos,f=q.top().times;
            q.pop();
            vis[u][f]=0;
            for(int i=Head[u];i;i=e[i].next){
                int v=e[i].to;
                if(dis[v][f]>dis[u][f]+e[i].w){
                    dis[v][f]=dis[u][f]+e[i].w;
                    if(!vis[v][f]){
                        vis[v][f]=1;
                        q.push(HA{v,dis[v][f],f});
                    }
                }
                if(f<k&&dis[v][f+1]>dis[u][f]){
                    dis[v][f+1]=dis[u][f];
                    if(!vis[v][f+1]){
                        vis[v][f+1]=1;
                        q.push(HA{v,dis[v][f+1],f+1});
                    }
                }
            }
        }
    }
    int main()
    {    
        fread(ch,1,ch_top,stdin);
        n=read(); m=read(); k=read();
        s=read(); t=read();
        int x,y,w;
        for(int i=1;i<=m;i++){
            x=read(); y=read(); w=read();
            e[++num].to=y;
            e[num].w=w;
            e[num].next=Head[x];
            Head[x]=num;
            e[++num].to=x;
            e[num].w=w;
            e[num].next=Head[y];
            Head[y]=num;
        }
        SPFA();
        write(dis[t][k]);
        fwrite(ch,1,now_w-ch,stdout);
        return 0;
    }
  • 相关阅读:
    Centos 6.5 在 Dell 服务器安装的记录
    【转载】你真的了解补码吗
    【转载】我对补码的理解
    记录一下家里双路由实现wifi漫游功能
    中国大学MOOC | C语言程序设计入门 第8周编程练习 翁恺
    华为卡刷包线刷方法
    串口通信
    端口复用和端口重映射
    软件仿真和硬件仿真
    FPGA之四位LED灯
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/9404075.html
Copyright © 2011-2022 走看看