zoukankan      html  css  js  c++  java
  • 堆优化dijkstra

    单源最短路径

    题目链接:https://www.luogu.org/problemnew/show/P4779

    直到做了这个题才发现我之前写的堆优化dijkstra一直是错的。。

     

    这个堆优化其实很容易理解,将枚举最小值改为从堆中取出最小值,改变dis时入堆即可

    用单调队列维护时必须有两个值:点的编号和当前的距离

    以距离为标准从小到大排序, 每次去除最小的

     

    以前错的原因:

    堆中只维护了点的编号,以dis[x]排序

    这样做在取出一个元素操作后,会更新它周围一圈元素的dis值,

    若它周围一圈元素中有的在堆中,dis值被改变后,堆的性质会遭到破坏

    然而由于这道题太水了,我一直认为这是对的

     

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define il inline
    #define re register
    #define N 100010
    #define M 200010
    int n,m,s,dis[N];
    struct FUCK{
        int p;
        int cost;
    };
    struct cmp{
        il bool operator()(FUCK ZYX,FUCK YSH){
            return ZYX.cost>YSH.cost;
        }
    };
    priority_queue<FUCK,vector<FUCK>,cmp> q;
    il int read(){
        int x=0; char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
        return x;
    }
    void write(int x){
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    struct NODE{
        int to,w,next;
    } e[M];
    int Head[N],num;
    il void add(int x,int y,int w){
        e[++num].to=y;
        e[num].w=w;
        e[num].next=Head[x];
        Head[x]=num;
    }
    bool used[N];
    int main()
    {
        n=read(); m=read(); s=read();
        int x,y,w;
        for(re int i=1;i<=m;i++){
            x=read(); y=read(); w=read();
            add(x,y,w);
        }
        memset(dis,127,sizeof(dis));
        dis[s]=0;
        q.push((FUCK){s,0});
        while(!q.empty()){
            FUCK k=q.top();
            q.pop();
            int u=k.p;
            if(used[u]) continue;
            used[u]=1;
            for(re int i=Head[u];i;i=e[i].next){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].w){
                    dis[v]=dis[u]+e[i].w;
                    q.push(FUCK{v,dis[v]});
                }
            }
        }
        for(re int i=1;i<=n;i++)
         write(dis[i]),putchar(' ');
        return 0;
    }
  • 相关阅读:
    .NET自动化测试手记(2) 实例:点击计算器按钮
    解决httpwebrequest无法通过使用代理的局域网获取response的问题
    iOS开发之SQLite
    iOS开发之AVAudioPlayer 音频播放
    iOS开发 键盘添加工具条(toolbar)
    UIPickerView中的实例方法
    TextField
    UISearchBar和UISearchDisplayController
    Objectivec 字符串遍历的几种方法
    《Write ObjectiveC Code》学习笔记
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/8506266.html
Copyright © 2011-2022 走看看