zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Repeater自定义翻页 存储过程实现
    Redis常用命令
    常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例
    网站转接支付宝解决方案
    如何有效抓取SQL Server的BLOCKING信息
    SVN 冲突文件详解
    JavaScript可否多线程? 深入理解JavaScript定时机制
    MS SQL Server:分区表、分区索引详解
    支付宝外部商家购物流程
    排查数据库性能的常用sql语句
  • 原文地址:https://www.cnblogs.com/miserweyte/p/11356177.html
Copyright © 2011-2022 走看看