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。不过有的数据水的还是能过许多点。

  • 相关阅读:
    windows下搭建基于eclipse插件的GoLang开发环境
    vtk类之vtkImageReslice:基本算法,对体数据沿着轴进行切片
    vtk类之vtkTextureMapToSphere:纹理映射算法, 映射球体纹理
    wxpython 之 GDI 画刷Brush(三)
    c# 获取Rss数据
    C# 基础知识系列之面向对象基础
    SilverLight 得到文件绝对路径
    SilverLight C# 读取并修改App.config文件
    Silverlight 脱离浏览器
    C# 中New关键字的用法
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039500.html
Copyright © 2011-2022 走看看