• 单源最短路问题--朴素Dijkstra & 堆优化Dijkstra


    许久没有写博客,更新一下~

    Dijkstra两种典型写法

    1. 朴素Dijkstra     时间复杂度O(N^2)       适用:稠密图(点较少,分布密集)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    const int N=510;
    int n, m;
    int g[N][N], dist[N];
    bool st[N];
    
    int dijkstra()
    {
        memset(dist, 0x3f, sizeof(dist));
        dist[1]=0;
        for(int i=0; i<n; i++)
        {
            int t=-1;
            for(int j=1; j<=n; j++)
                if(!st[j] && (t==-1 || dist[t]>dist[j])) t=j;  //1. S中求最近的点,目前到起点的最小值
            st[t]=true;                 //2. 更新状态 t点到起点的最短路已经被确定
            for(int j=1; j<=n; j++)
                dist[j]=min(dist[j], dist[t]+g[t][j]);  //3. 用t更新,经过t可能构成的最短路
        }
        if(dist[n]==0x3f3f3f3f) return -1;
        else return dist[n];
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        memset(g, 0x3f, sizeof(g));
        for(int i=0; i<m; i++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            g[x][y]=min(g[x][y], z);
        }
        printf("%d
    ", dijkstra());
        return 0;
    }

    2. 堆优化Dijkstra  时间复杂度:O(m*log(n))   适合:稀疏图(边较多,点分布不集中)

    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    const int N=1e5+10;
    typedef pair<int, int> PII;
    int h[N], e[N], ne[N], w[N], idx;
    bool st[N];
    int n, m, dist[N];
    
    void add(int a, int b, int c)
    {
        e[idx]=b, ne[idx]=h[a], w[idx]=c, h[a]=idx++;    //建图
    }
    
    int dijkstra()
    {
        memset(dist, 0x3f, sizeof(dist));
        dist[1]=0;
        priority_queue<PII, vector<PII>, greater<PII>> heap;
        heap.push({0, 1});
        while(heap.size())
        {
            auto u=heap.top();      //取已确定到起点最小距离的点, O(1)
            heap.pop();
            int ver=u.second, dis=u.first;
            if(st[ver]) continue;
            st[ver]=true;
            for(int i=h[ver]; i!=-1; i=ne[i])
            {
                int j=e[i];
                if(!st[j] && dist[j]>dis+w[i])    //这里的dis可以写成dist[ver]
                {                                   //用pair存储距离、节点编号,为了以 距离 建堆
                    dist[j]=dist[ver]+w[i];     //注意这里的w[i] , 边的权值存储在节点对应位置
                    heap.push({dist[j], j});  //入堆,O(log(n))
                }                                //每一条边都会被遍历到,总时间复杂度O(m*log(n))
            }
        }
        if(dist[n]==0x3f3f3f3f) return -1;
        else return dist[n];
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        memset(h, -1, sizeof(h));
        while(m--)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            add(a, b, c);
        }
        printf("%d
    ", dijkstra());
    
        return 0;
    }
        
  • 相关阅读:
    【转】RocketMQ事务消费和顺序消费详解
    RocketMQ初探(五)之RocketMQ4.2.6集群部署(单Master+双Master+2m+2s+async异步复制)
    Spring定时器Quartz的使用
    RocketMQ初探(四)之RocketMQ4.x版本可视化管理控制台rocketmq-console-ng搭建(Apache)
    RocketMQ入门(简介、特点)
    RocketMQ初探(二)之RocketMQ3.26版本搭建(含简单Demo测试案例)
    RocketMQ初探(一)
    tomcat详解
    HDFS读写流程
    RabbitMQ
  • 原文地址:https://www.cnblogs.com/Dawn-bin/p/12548404.html
Copyright © 2020-2023  润新知