zoukankan      html  css  js  c++  java
  • #单源最短路 #Dijkstra 学习心得 20.8.13

    最短路

    最短路学习思路图

    朴素Dijkstra

    链接
    1、思路
    *0、定义数组 dis[n] (从1到其它点的距离), s[n](已经确定最短距离的点);
    *1、初始化 dis[1] = 0, dis[其它点] = 正无穷;
    *2、 for(1 ~ n);——————————循环 n 次,更新所有的点 t;
    *3 找到 不在s中的,距离最近的点 t;
    *4 将t加入s;
    *5 用t更新其它点的距离;————————循环n次
    (这里是两 层 循环, 所以时间复杂度是 n^2)
    *6 返回

    例题
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 510;
    
    int n, m;
    int g[N][N];
    int djs[N];
    bool s[N];
    
    int djst(){
        memset(djs, 0x3f3f3f3f, sizeof djs);				/* *1 */
        djs[1] = 0;											/* *1 */
        
        for(int i = 0; i < n; i ++){						/* *2 */
            int t = -1;										/* *3 */
            for(int j = 1; j <= n; j ++)					/* *3 */
                if(!s[j] && (t == -1 || djs[t] > djs[j]))	/* *3 */ 
                    t = j;									/* *3 */
                
            s[t] = 1;										/* *4 */
            
            for(int j = 1; j <= n; j ++)					/* *5 */
                djs[j] = min(djs[j], djs[t] + g[t][j]);		/* *5 */
        }
        if(djs[n] == 0x3f3f3f3f) return -1;					/* *6 */
        return djs[n];										/* *6 */
    }
    
    int main(){
        cin >> n >> m;
        memset(g, 0x3f3f3f3f, sizeof g);
        while(m --){
            int a, b, c;
            cin >> a >>b >>c;
            g[a][b] = min(g[a][b], c);
        }
        int t = djst();
        
        cout << t;
        
        return 0;
    }
    /*
    0x3f3f3f3f 代表 正无穷。
    */
    

    优化Dijkstra :

    题目链接
    优先队列的函数补充:
    优先队列数据结构(堆)的函数用法 20.10.17

    可以更新的地方:
    分析:
    
    
    *2、 for(1 ~ n);·;
    *3	找到 不在s中的,距离最近的点 t;——————*2、*3共循环 n^2 次来找点 t;(用小根堆堆来做可时间O(n))
    	,也就是用优先队列,优化后为O(log n)
    
    	就是这里可以优化
     for(int j = 1; j <= n; j ++)					/* *3 */
                if(!s[j] && (t == -1 || djs[t] > djs[j]))	/* *3 */ 
                    t = j;			
    
    *4	将t加入s;																		——————————————————这里是n次
    *5	用t更新其它点的距离;						—————————————具体操作时m次,遍历所有的边来更新
    堆优化后 整个计算量最大是 O(m log n)。
    堆的写法:
    手写或用优先队列,两者时间是一个级别的,用优先队列,不需要手写堆。
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 150010;
    
    int n, m;
    int djs[N];
    bool st[N];
    int ne[N], e[N], h[N], w[N], idx = 0;
    
    typedef pair<int ,int> P;//距离1的距离,以及点号, 这里默认是按照第一个元素来排序的
    
    void add(int a, int b, int c){
        e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
    }
    
    int djst(){
        memset(djs, 0x3f, sizeof djs);
        djs[1] = 0;
        
        priority_queue< P, vector<P>, greater<P> > heap;/* *1 */
        heap.push( {0, 1} );
        
        while(heap.size()){
            auto t = heap.top();
            heap.pop();
            
            int ver = t.second, distance = t.first;
            if(st[ver]) continue;
            
            st[ver] = 1;								/* *2 */
            
            for(int i = h[ver]; i != -1; i = ne[i]){
                int j = e[i];
                if(djs[j] > distance + w[i]){
                    djs[j] = distance + w[i];
                    heap.push({djs[j], j});
                }
            }
        }       
       
        if(djs[n] == 0x3f3f3f3f) return -1;
        return djs[n];
    }
    
    int main(){
        cin >> n >> m;
        memset(h, -1, sizeof h);
        while(m --){
            int a, b, c;
            cin >> a >>b >>c;
            add(a, b, c);
        }
        cout << djst() << endl;
        return 0;
    }
    

    给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为非负值。

    请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。

    输入格式
    第一行包含整数n和m。

    接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

    输出格式
    输出一个整数,表示1号点到n号点的最短距离。

    如果路径不存在,则输出-1。

    数据范围
    1≤n,m≤1.5×105,
    图中涉及边长均不小于0,且不超过10000。

    输入样例:
    3 3
    1 2 2
    2 3 1
    1 3 4
    输出样例:
    3
    *1 强调:“>”不要两个拼在一起。
    less是从大到小,greater是从小到大。
    第一个参数为数据类型。
    第二个参数为容器类型。
    第三个参数为比较函数。
    *2 千万不要忘记。

  • 相关阅读:
    微软外服 AlI In One
    js 循环多次和循环一次的时间的性能对比 All In One
    vue inject All In One
    Excel 表格数据倒置 All In One
    SVG tickets All In One
    OH MY ZSH All In One
    js array for loop performance compare All In One
    mac terminal show You have new mail All In one
    新闻视频 26 制作母版页
    转自牛腩 母版页和相对路径
  • 原文地址:https://www.cnblogs.com/yuanyulin/p/14026759.html
Copyright © 2011-2022 走看看