zoukankan      html  css  js  c++  java
  • Dijkstra+优先队列 堆优化

    关于堆优化

    传统(Dijkstra),在选取中转站时,是遍历取当前最小距离节点,但是我们其实可以利用小根堆(STL的priority_queue)优化这个过程,从而大大降低复杂((O(V^2+E) -> O((V+E)lgV))

    另外,需要注意,因为(Dijkstra)本质是贪心,每一次选择中转站必须保证最优,而负边权会使当前中转站不为最优,所以不能处理含有负边权的图

    代码

    #include <cstdio>
    #include <queue>
    #include <vector>
    #define MAXN 200010
    #define INF 0x3fffffff
    using namespace std;
    struct edge{
        int v,w;
        edge(int v, int w):v(v),w(w){}
    };
    vector <edge> mp[MAXN];
    int dis[MAXN];
    bool vis[MAXN];
    int n,m,s;
    struct node{
        int v,dis;
        node(int v, int dis):v(v),dis(dis){}
        const bool operator < (const node &a) const{
            return a.dis < dis;
        }
    };
    priority_queue <node> q;
    
    int read(){
        char ch;int s=0;
        ch = getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
        return s;
    }
    
    void dj(){
        for(register int i=1;i<=n;i++)
            dis[i]=INF;
        dis[s]=0;
        q.push(node(s, 0));
        while(!q.empty()){
            node cur = q.top();
            q.pop();
            if(vis[cur.v])  continue;
            vis[cur.v] = 1;
            for(register int i=0;i<mp[cur.v].size();i++){
                edge to = mp[cur.v][i];
                if(vis[to.v]) continue;
                if(dis[to.v]>to.w+dis[cur.v]){
                    dis[to.v]=to.w+dis[cur.v], q.push(node(to.v, dis[to.v]));
                }
            }
        }
        for(register int i=1;i<=n;i++)
            printf("%d ", dis[i]);
    }
    
    int main()
    {
        n=read(),m=read(),s=read();
        for(register int i=1;i<=m;i++){
            int u,v,w;
            u=read(),v=read(),w=read();
            mp[u].push_back(edge(v, w));
        }
        dj();
        return 0;
    }
    

    参考

    水郁 - Dijkstra+heap和SPFA的区别

  • 相关阅读:
    额外的 string 操作
    vector 对象是如何增长的
    顺序容器操作
    容器库概览
    顺序容器概述
    特定容器算法
    泛型算法结构
    再探迭代器
    定制操作
    使用关联容器
  • 原文地址:https://www.cnblogs.com/santiego/p/10458039.html
Copyright © 2011-2022 走看看