• Dijkstra 算法求最短路径


     以上是一个有向无环图,从V1到V2所花费的代价是2,从V1到V3的代价是3,...,以此类推,求出从V1到其他各个点的最短路径。

    Dijkstra思路:

    1. 建立两个容器,容器S中装着已经求出最短路径的顶点,初始时只有V1,另外一个容器U装着V1到其他顶点的代价,初始时都为无穷大。

    2. 在图中遍历与V1直接相连的顶点V2和V3,发现(V1,V3)=3是最小的,此时将V3加入容器S,并且将V3移出U,得 S={V1=0,V3=3},U={V2=4,V4=∞,V5=∞,V6=∞}

    3. 以V3为中点,更新U中的其他点到V1的距离,取最小值。如 (V1,V3) + (V3,V4) = 3+3 = 6 < U[V4]=∞,所以U[V4]=6,依次类推,U[V5]=13,的U={V2=4,V4=6,V5=13,V6=∞}

    4. 找出U中最小的值,U[V2]=4,将V2加入到容器S中,并从U中移出,得 S={V1=0,V3=3,V2=4},U={V4=6,V5=13,V6=∞}

    5. 以V2为中点,更新U中的值,发现V4不用更新,因为(V1,V2)+(V2,V4)=10 < U[V4]=6,但是要更新V5,因为(V1,V2)+(V2,V5)=11 < U[V5]=13,得U={V4=6,V5=11,V6=∞}

    6. 找出U中最小的值,U[V4]=6,将V4加入到容器S中,并从U中移出,S={V1=0,V3=3,V2=4,V4=6}, U={V5=11,V6=∞}

    7. 以V4为中点,更新U中的值,发现(V1,V4)+(V4+V5)=6+2=8 < U[V5]=11,需要更新V5,此外,(V1,V4)+(V4,V6)=6+8=14 < U[V6]=∞ 也需要更新V6, 得出,U={V5=8,V6=14}

    8. 从U中找到最小值,U[V5]=8,将V5加入到容器S中,并从U中移出,得S={V1=0,V3=3,V2=4,V4=6,V5=8},U={V6=14}

    9. 以V5为中心,更新U中的值,发现(V1,V5)+(V5,V6)=8+5=13 < U[V6]=14,所以更新U={V6=13}

    10. 将剩下的V6加入到容器S中,遍历结束。此时,容器S中就是从V1到各个顶点的最小值。

     以上的4~5、5~6、7~8 都是重复的行为,因为总结出遍历规律:

    if (V1,Vx) + (Vx, Vy) < U[Vy]

      U[Vy] = (V1,Vx) + (Vx,Vy)

    这也是Dijkstra的核心思想。

    时间复杂度

    Dijkstra 算法的时间花费主要体现在重复的4~5步骤中,也就是不断的遍历顶点和边数,所有应该为O(V * E) ,近似可以等于O(E^2)

    LeetCode试题

    743. 网络延迟时间

    有 n 个网络节点,标记为 1 到 n。

    给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。

    现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。

    示例 1:

     

    输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
    输出:2
    示例 2:

    输入:times = [[1,2,1]], n = 2, k = 1
    输出:1
    示例 3:

    输入:times = [[1,2,1]], n = 2, k = 2
    输出:-1

    C#实现解题:

     1         public int NetworkDelayTime(int[][] times, int n, int k)
     2         {
     3             int ans = 0;
     4             int len = n;
     5             int[] s = new int[n+1];
     6             s[k] = 0;
     7             Dictionary<int, int> u = new Dictionary<int, int>();
     8             
     9             //初始化U的各个节点为无穷大
    10             for(int i = 1; i <= n; ++i)
    11             {
    12                 if (i != k)
    13                 {
    14                     u.Add(i, Int32.MaxValue);
    15                 }
    16             }
    17             
    18             //找出直接与K相邻的点,并更新U
    19             for (int i = 0; i < times.Length; ++i)
    20             {
    21                 var arr = times[i];
    22                 if (arr[0] == k)
    23                 {
    24                     u[arr[1]] = arr[2];
    25                 }
    26             }
    27 
    28             len--;
    29 
    30             while (len > 0)
    31             {
    32                 int minTemp = Int32.MaxValue;
    33                 int index = -1;
    34                 var uIt = u.GetEnumerator();
    35                 while (uIt.MoveNext())
    36                 {//找到U中最小的点
    37                     if (uIt.Current.Value < minTemp)
    38                     {
    39                         minTemp = uIt.Current.Value;
    40                         index = uIt.Current.Key;
    41                     }
    42                 }
    43 
    44                 if (index <= -1)
    45                 {
    46                     return -1;
    47                 }
    48 
    49                 s[index] = minTemp;
    50                 u.Remove(index);
    51                 if (ans < minTemp)
    52                 {
    53                     ans = minTemp;
    54                 }
    55 
    56                 if (u.Count <= 0)
    57                 {
    58                     break;
    59                 }
    60                 
    61                 //以index点为中心,更新U中的点的值
    62                 for (int i = 1; i <= n; ++i)
    63                 {
    64                     for (int j = 0; j < times.Length; ++j)
    65                     {
    66                         int[] timeArr = times[j];
    67                         if (timeArr[0] == index && timeArr[1] == i && u.ContainsKey(i) && s[index] + timeArr[2] < u[i])
    68                         {
    69                             u[i] = s[index] + timeArr[2];
    70                         }
    71                     }
    72                 }
    73 
    74                 len--;
    75 
    76             }
    77 
    78             return ans;
    79         }
  • 相关阅读:
    uwsgi+nginx+django
    uwsgi怎么启动停止
    centos7 命令
    django 配置静态文件
    centos7 安装node
    python 字符串拼接
    Python 编码
    python 文件夹递归
    ArcGIS二次开发的几种方式
    集合的操作
  • 原文地址:https://www.cnblogs.com/moxiangfeng/p/16390590.html
Copyright © 2020-2023  润新知