zoukankan      html  css  js  c++  java
  • 【模板】Dijkstra的heap优化

    为了将最小费用最大流的spfa优化,决定将spfa换成heap优化的Dijkstra。(dijkstra不能处理负边权)

    所以还得现学。。。

    白点表示已经确定最短路径的点。

    蓝点表示还未确定最短路径的点。

    因为普通的dijkstra是每次从蓝点中找到一个距离起点的距离最小的点,然后把这个点变成白点,随后枚举这个点相连的所有蓝点,若以此白点为中转点到达相连蓝点的路径更短的话就更新蓝点到起点的最短距离。

    这个时间复杂度是O(n^2)的。

    显然,枚举在枚举到起点最小距离的蓝点时,可以运用heap优化。

    所以时间复杂度就降为O((n+m)logn)。(n为顶点数,m为边数)

    大部分情况下还是跑不过spfa的,慎用。

    stl大法好。

    ——附带码

     1 #include <cstdio>
     2 #include <queue>
     3 #include <cstring>
     4 #define Heap pair<int, int>
     5 //第一个int存的是到起点的距离,第二个int存的是点的编号
     6 
     7 using namespace std;
     8 
     9 const int INF = 2147483647;
    10 int n, m, t, cnt;
    11 int next[1000001], to[1000001], val[1000001], head[10001], dis[10001];
    12 bool vis[1000001];
    13 priority_queue <Heap, vector <Heap>, greater <Heap> > q;
    14 //按照第一个int从小到大排序 
    15 
    16 inline void add(int a, int b, int c)
    17 {
    18     to[cnt] = b;
    19     val[cnt] = c;
    20     next[cnt] = head[a];
    21     head[a] = cnt++;
    22 }
    23 
    24 inline void Dijkstra(int s)//以s为起点 
    25 {
    26     int i, u, v;
    27     Heap x;
    28     for(i = 1; i <= n; i++) dis[i] = INF;
    29     dis[s] = 0;
    30     q.push(make_pair(0, s));//入队 
    31     while(!q.empty())
    32     {
    33         x = q.top();
    34         q.pop();
    35         u = x.second;
    36         if(vis[u]) continue;//判断是否已经是最短路径上的点 
    37         vis[u] = 1;
    38         for(i = head[u]; i != -1; i = next[i])//更新距离 
    39         {
    40             v = to[i];
    41             if(dis[v] > dis[u] + val[i])
    42             {
    43                 dis[v] = dis[u] + val[i];
    44                 q.push(make_pair(dis[v], v));
    45             }
    46         }
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     int i, j, a, b, c, s;
    53     scanf("%d %d %d", &n, &m, &s);
    54     memset(head, -1, sizeof(head));
    55     for(i = 1; i <= m; i++)
    56     {
    57         scanf("%d %d %d", &a, &b, &c);
    58         add(a, b, c);
    59     }
    60     Dijkstra(s);
    61     for(i = 1; i <= n; i++) printf("%d ", dis[i]);
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    SSH框架的简单上传功能的实现
    笔记:《C++ Primer》第3章
    笔记:《C++ Primer》第1章和第2章
    tcl脚本学习十三:列表命令集
    tcl脚本学习十二: upvar的学习
    tcl脚本学习十一:proc应用 (带默认参数)
    tcl脚本学习十:proc 子函数的使用
    tcl脚本学习八:while循环的使用
    tcl脚本学习九:for循环的学习
    tcl脚本学习七:if的学习
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6690846.html
Copyright © 2011-2022 走看看