zoukankan      html  css  js  c++  java
  • 最短路径算法之二——Dijkstra算法

    Dijkstra算法

      Dijkstra算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

      注意该算法要求图中不存在负权边

      首先我们来定义一个二维数组Edge[MAXN][MAXN]来存储图的信息。

     

        这个图的Edge数组初始化以后为

     

        我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下。

     

      这个dis数组中存的是最短路的估计值

      通过Dijkstra算法来松弛后,dis存的为从初始点到各点的精确值(最短路径)了。

     

    Dijkstra算法实现如下(HDU1548为例):

     

     1 #include<stdio.h>
     2 #include<limits.h>
     3 #include<iostream>
     4 #include<string.h>
     5 #define MAXN 200
     6 using namespace std;
     7 int edge[MAXN+10][MAXN+10];
     8 int dis[MAXN+10];
     9 bool vis[MAXN+10];
    10 int T,S,D,N,k;
    11 void dijkstra(int begin)
    12 {
    13     memset(vis,0,sizeof(vis));
    14     for (int i=1; i<=T; i++)
    15         dis[i]=INT_MAX;
    16     dis[begin]=0;
    17     for (int t=1; t<=T; t++)
    18     {
    19         vis[begin]=1;
    20         for (int i=1; i<=T; i++)
    21             if (!vis[i]&&edge[begin][i]!=INT_MAX&&dis[begin]+edge[begin][i]<dis[i])
    22                 dis[i]=dis[begin]+edge[begin][i];
    23         int min=INT_MAX;
    24         for (int j=1; j<=T; j++)
    25             if (!vis[j]&&min>dis[j])
    26             {
    27                 min=dis[j];
    28                 begin=j;
    29             }
    30     }
    31 }
    32 int main()
    33 {
    34     int begin,end;
    35     while (cin>>T)
    36     {
    37         if (T==0) break;
    38         for (int i=1; i<=MAXN; i++)
    39             for (int j=1; j<=MAXN; j++)
    40                 edge[i][j]=INT_MAX;
    41         scanf("%d %d",&begin,&end);
    42         int t;
    43         for (int i=1; i<=T; i++)
    44         {
    45             scanf("%d",&t);
    46             if (i+t<=T) edge[i][i+t]=1;
    47             if (i-t>=1) edge[i][i-t]=1;
    48         }
    49         dijkstra(begin);
    50         if (dis[end]!=INT_MAX) printf("%d
    ",dis[end]);
    51         else printf("-1
    ");
    52     }
    53     return 0;
    54 }

     

    时间复杂度:O(N^2)

    使用邻接表(见下文)优化后可达到O(MlogN) 

    PS:M在最坏情况下可能为N^2!!

    部分图片文字摘自于啊哈磊的blog。

     

  • 相关阅读:
    记录按钮点击次数,点击三次之后跳转页面
    HTML拖放
    .Net实现发送邮件功能
    HTTP 400 错误
    方法(参数的传递)
    方法
    c# 属性 (get、set)
    Python和C++交互
    从Windows远程Ubuntu
    Eclipse+Tomcat WEB开发配置
  • 原文地址:https://www.cnblogs.com/Enumz/p/3862660.html
Copyright © 2011-2022 走看看