zoukankan      html  css  js  c++  java
  • 堆优化/zkw线段树优化 dijkstra

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 100005;
    const int MAXM = 200005;
    inline void read(int &num)
    {
        char ch; int flag=1;
        while(!isdigit(ch=getchar()))if(ch=='-')flag=-flag;
        for(num=ch-'0';isdigit(ch=getchar());num=num*10+ch-'0');
    }
    int N, M, S;
    
    int fir[MAXN], to[MAXM], nxt[MAXM], w[MAXM], cnt;
    inline void Add(int u, int v, int wt)
    {
        to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; w[cnt] = wt;
    }
    
    int dis[MAXN];
    bool vis[MAXN];
    #define pii pair<int,int>
    #define mp make_pair
    priority_queue<pii, vector<pii>, greater<pii> >q;
    inline void Dijkstra_heap(int s)
    {
        memset(dis, 0x3f, sizeof dis);
        memset(vis, 0, sizeof vis);
        dis[s] = 0; q.push(mp(0, s));
        while(!q.empty())
        {
            int u = q.top().second; q.pop();
            if(vis[u]) continue;
            vis[u] = 1;
            for(int i = fir[u]; i; i = nxt[i])
                if(!vis[to[i]] && dis[to[i]] > dis[u] + w[i])
                    q.push(mp(dis[to[i]]=dis[u] + w[i], to[i]));
        }
    }
    
    int Min[MAXN<<2], hp[MAXN], bit;
    
    inline void Modify(int x) { for(x>>=1; x; x>>=1) Min[x] = (hp[Min[x<<1]] < hp[Min[x<<1|1]]) ? Min[x<<1] : Min[x<<1|1]; }
    inline void Build() { for(bit = 1; bit <= N+1; bit<<=1); }
    inline void Update(int x, int dist) { hp[x] = dist; Modify(bit+x); }
    
    inline void Dijkstra_segment_tree(int s)
    {
    	memset(dis, -1, sizeof dis);
    	memset(hp, 0x3f, sizeof hp);
    	Build(); hp[s] = 0;
    	for(int i = 1; i <= N; i++) Min[bit+i] = i, Update(i, hp[i]);
    	for(int i = 1; i <= N; i++)
    	{
    		int u = Min[1];
    		dis[u] = hp[u];
    		Update(u, 0x3f3f3f3f);
    		for(int j = fir[u]; j; j = nxt[j])
    			if(dis[to[j]] == -1 && hp[to[j]] > dis[u] + w[j])
    				Update(to[j], dis[u] + w[j]);
    	}
    }
    
    int main ()
    {
        int x, y, z, S;
        read(N), read(M), read(S);
        for(int i = 1; i <= M; i++)
            read(x), read(y), read(z), Add(x, y, z);
        Dijkstra_heap(S);
        //Dijkstra_segment_tree(S);
    	for(int i = 1; i < N; i++) printf("%d ", dis[i]);
        printf("%d
    ", dis[N]);
    }

    CAUTION!CAUTION!注意堆优化dij不能这么写:!!!!

    int dis[MAXN];
    bool vis[MAXN];
    struct cmp
    {
        bool operator ()(int a, int b) //重载优先级低的(1:a优先级低 0:b优先级低)
        {
            return dis[a] > dis[b]; //此处有问题
        }
    };
    priority_queue<int, vector<int>, cmp>q;
    void Dijkstra_heap(int s)
    {
        memset(dis, 0x7f, sizeof dis);
        memset(vis, 0, sizeof vis);
        dis[s] = 0; q.push(s);
        while(!q.empty())
        {
            int u = q.top(); q.pop();
            if(vis[u]) continue;
            vis[u] = 1;
            for(int i = fir[u]; i; i = nxt[i])
                if(!vis[to[i]] && dis[to[i]] > dis[u] + w[i])
                {
                    dis[to[i]] = dis[u] + w[i];
                    q.push(to[i]);
                }
        }
    }

    由于优先队列的有序性是取决于插入的位置,当dis值在外面被修改,队列的元素顺序不会改变,于是就失去了有序性。在luogu的最短路模板题(传送门)就会WA。不过有的数据水的还是能过许多点。

  • 相关阅读:
    iOS企业证书网页分发全过程具体解释(图文并茂史无前例的具体哦)
    MySql按周/月/日分组统计数据的方法
    Linux
    video_capture模块分析
    Go语言核心之美 1.1-命名篇
    《JAVA程序设计》实训第二天——《猜猜看》游戏
    openssl之EVP系列之10---EVP_Sign系列函数介绍
    从字节码指令看重写在JVM中的实现
    Dalvik虚拟机垃圾收集(GC)过程分析
    call to OpenGL ES API with no current context 和Fatal signal 11
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039500.html
Copyright © 2011-2022 走看看