• Dijkstra算法 笔记与思路整理


    该文章可能存在硬伤与不妥,不能作为教程阅读。(因为我真的鶸

    Dij作为单源最短路算法,需要先确定一个起点。Dij的函数主体为维护每个节点的dis和vis两个变量。dis表示该点距离起点的最短路权值和,vis存储该点是否被访问过

    设点数为n,无向边数为m,则要进行n次循环,每次循环中找出一个dis最小且vis不为真的点进行松弛操作。

    这里抄一段百科:

    松弛操作是指对于每个顶点v∈V,都设置一个属性g[v],用来描述从源点s到v的最短路径上权值的上界,称为最短路径估计(shortest-path estimate)。

    松弛操作主要代码:

    if(dis[g[i].to] > g[i].val + curr.dis)
        dis[g[i].to] = g[i].val + curr.dis;

    然后就是优化:

      (1)判断最小值的循环可用优先队列优化

      (2)使用优先队列后可以直接判断堆中是否剩余元素来循环

      (3)使用链表存储图,松弛操作只遍历相关的边

    模板:

    #include <bits/stdc++.h>
    #define maxn 10010
    #define maxm 10010
    using namespace std;
    
    struct edge{
        int to, val, next;
    };
    edge g[maxm];
    int first[maxn], edge_cnt = 0;
    
    struct node{
        int pos, dis;
    };
    priority_queue<node> q;
    bool operator<(const node a, const node b){
        return a.dis > b.dis;
    }
    int dis[maxn], vis[maxn];
    
    int n, m;
    void in_put(){
        scanf("%d%d", &n, &m);    //n nodes, m edges
        for(int i=0; i<m; i++){
            int f, t, val;
            scanf("%d%d%d", &f, &val, &t);
            g[edge_cnt] = (edge){t, val, 0};
            g[edge_cnt].next = first[f];
            first[f] = edge_cnt;
            edge_cnt ++;
        }
    }
    void dijkstra(int start){
        vis[start] = 1;
        dis[start] = 0;
        q.push((node){start, dis[start]});
        while(q.size()){
            node curr = q.top();
            q.pop();
            int from = curr.pos;
            for(int i = first[from]; i ; i = g[i].next){
                if(dis[g[i].to] > g[i].val + curr.dis){
                    dis[g[i].to] = g[i].val + curr.dis;
                    q.push((node){g[i].to, dis[g[i].to]});
                }
            }
        }
        
    }
    int main(){
    //    freopen(".in", "r", stdin);
    //    freopen(".out", "w", stdout);
        memset(dis, 0x3f, sizeof(dis));
        in_put();
        dijkstra();
        return 0;
    }
  • 相关阅读:
    pipelinewise 学习二 创建一个简单的pipeline
    pipelinewise 学习一 docker方式安装
    Supercharging your ETL with Airflow and Singer
    ubuntu中使用 alien安装rpm包
    PipelineWise illustrates the power of Singer
    pipelinewise 基于singer 指南的的数据pipeline 工具
    关于singer elt 的几篇很不错的文章
    npkill 一个方便的npm 包清理工具
    kuma docker-compose 环境试用
    kuma 学习四 策略
  • 原文地址:https://www.cnblogs.com/miserweyte/p/11356177.html
Copyright © 2020-2023  润新知