• dijkstra最短路算法


    原理

    1. 一开始整张图没有边, 只有一个起点, 设它的距离向量为1.
    2. 更新与起点有连边的点的距离向量.
    3. 取目前距离向量最小的点, 更新与它相连的点的距离向量.
      (可以证明这个距离相连最小的点其距离一定是起点与它的最短距离, 因为若不是最短距离, 则一定会由其它的点更新而来, 而没有距离更小的点).
    4. 更新多次能得到最终所有点的最短距离.

    实现

    使用堆优化寻找最短距离的点的过程.
    注意细节问题, 如果一个点已经被执行过[3]步骤, 那么再对它执行一次[3]步骤就毫无意义了, 所以要记录一下每个点是否被更新过.
    这个问题我是在多次超时模板题之后看讨论区发现的.

    虽然说是用堆优化, 实际上还是用优先队列priority_queue多一些.另外, pb_ds里面的优先队列好像还要慢一些.

    Code

    #include <time.h>
    #include <queue>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    const int N = 100005;
    const int inf = 0x3f3f3f3f;
    const int Inf = 0x7fffffff;
    using namespace std;
    
    const int MAXIN = 1 << 22;
    char IN[MAXIN], *SS = IN, *TT = IN;
    #define gc() (SS == TT && (TT = (SS = IN) + fread(IN, 1, MAXIN, stdin), SS == TT) ? EOF : *SS++)
    
    inline int read() {
        int now = 0; register char c = gc();
        for (; !isdigit(c); c = gc());
        for (; isdigit(c); now = now * 10 + c - '0', c = gc());
        return now;
    }
    
    struct Edge {
        int v, c; Edge* nxt;
        Edge() {}
        Edge(int _, int __, Edge* ___) : v(_), c(__), nxt(___) {}
    } *head[N], pool[400005];
    
    struct Pair{
        int dis, id;
        Pair(int _, int __) : dis(_), id(__) {}
        bool operator < (const Pair& o) const {
            return dis > o.dis;
        }
    };
    static int cnt = 0;
    #define new_Edge(u, v, c) (pool[cnt] = Edge(u, v, c), &pool[cnt++])
    #define AddEdge(u, v, c) head[u] = new_Edge(v, c, head[u])
    
    int dis[N], vis[N];
    
    void dijkstra(int s) {
        priority_queue<Pair> que;
        que.push(Pair(0, s));
        memset(dis, 0x3f, sizeof dis);
        dis[s] = false;
        while (not que.empty()) {
            int u = que.top().id; que.pop(); 
            if (vis[u]) continue; vis[u] = true;
            for (auto edge = head[u]; edge; edge = edge->nxt) {
                int v = edge->v;
                if (dis[v] > dis[u] + edge->c) {
                    dis[v] = dis[u] + edge->c;
                    que.push(Pair(dis[v], v));
                }
            }
        }
    }
    
    int main() {
        int n = read(), m = read(), s = read();
        for (int i = 0; i < m; i += 1) {
            int u, v, c;
            u = read(), v = read(), c = read();
            AddEdge(u, v, c);
        }
        dijkstra(s); 
        for (int i = 1; i <= n; i += 1)
            printf("%d ", dis[i] == inf ? Inf : dis[i]);
        return 0;
    }
    
  • 相关阅读:
    angular6 增加webpack配置 亲测可用
    Git 忽略提交 .gitignore
    pc 媒体查询
    angular vue通过node启动项目局域网内关闭防火墙无法访问的解决办法
    js判断isNumber(obj)
    hook
    javascript中this的四种用法
    JavaScript中闭包函数
    JavaScript(ES3)中的方法, 及bind apply call的使用
    ES6 箭头函数
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/9857337.html
Copyright © 2020-2023  润新知