dijkstra算法

来源:互联网 发布:淘宝商家发快递多少钱 编辑:程序博客网 时间:2024/06/03 23:58

        对滴,你们的博主又回来了,按照上一次博主所承诺的,今天博主和大家来聊一聊dijkstra算法——一种求单源点之间最短路径

算法。好啦,依照我的习惯,帅气的甩给大家一道《啊哈!算法》上的题目,简单的说就是求一个图中1号顶点到2、3、4、5、6

顶点的最短路程。输入的共有m+1行,第一行两个整数n和m。n表示顶点个数(顶点编号为1到n),m表示边的条数。接下来m

行,每行有3个数x y z,表示顶点x到顶点y边的权值为z。输出的只有一行,表示1号顶点到2、3、4、5、6号顶点的最短路径。下面

我将帅气的扔给大家一组输入样例:6  9

                                    1  2  1

                                    1  3  12

                                    2  3  9

                                    2  4  3

                                    3  5  5

                                    4  3  4

                                    4  5  13

                                    4  6  15

                                    5  6  4

        然后吧,输出的应该是:0  1  8  4  13  17。

        现在,我们来思考一下,这一次,我们依然用一个二维数组a来存储这个图的顶点之间边的关系,初始化后如下:

                                                                                                                                                                                                       1   2   3   4   5   6

                                                                                                                                                                                                                                                                         1  0  1  12  ∞  ∞  ∞

                                                                                                                                                                                                       2 ∞  0   9   3   

                                                                                                                                                                                                       3 ∞ ∞   0  ∞   5 

                                                                                                                                                                                                       4 ∞ ∞   4  0 1315

                                                                                                                                                                                                       5   ∞ ∞     0  4

                                                                                                                                                                                                       6   ∞  ∞ ∞  ∞  0

        我们还需要一个一位数组dis来存储1号顶点到其余各个顶点之间的最短路程,初始化后如下:1   2   3   4   5   6

                                                                                                                                                                        0   1 12   ∞  

        我们将此时的dis数组中的值称为“未确定值”。首先,我们可以先找一个离1号顶点最近的顶点,通过上面dis数组的值可知当

离1号顶点最近的是2号顶点。此时,dis[2]的值就从“未确定值”变成了“确定值”,也就是说1号顶点到2号顶点的最短路程就是

在dis[2]的值,也就是1。选择了2号顶点后,我们来看一看,与2号顶点相通的顶点有哪些呢?有3号顶点和4号顶点,我们先来看

看让1号顶点到3号顶点能不能通过2号顶点到3号顶点来使路程变短呢?也就是说,现在我们来比较一下dis[2]+a[2][3]和dis[3]的大

小。我们发现,dis[2]+a[2][3]=1+9=10,而dis[3]=12,dis[2]+a[2][3]<dis[3],所以我们可以把dis[3]更新,专业一点说呢就是“松

弛”,通过边来松弛1号顶点到其余各个顶点的路程。同理,按照这种思想,我们可以把dis[4]的值从∞松弛为4。

        重复整个操作,直到dis数组中所有的值都从“未确定值”变成了“确定值”,整个问题就解决了,dis数组的值就是最后输出的

值,即:0   1   8   4   13   17。简单的说,dijkstra算法的基本思想就是①找最近顶点②找相通顶点③松弛。

        下面给出dijkstra算法的核心语句:for(i=1;i<n;i++)

                                                                                          {

                                                                     min=99999999;

                                                                     for(j=1;j<=n;j++)

                                                                     {

                                                                         if(vis[j]==0 && dis[j]<min)//此处vis数组用来标记

                                                                         {

                                                                                                     min=dis[j];

                                                                             flag=j;

                                                                         }

                                                                     }

                                                                     vis[flag]=1;

                                                                     for(k=1;k<=n;k++)

                                                                     {

                                                                         if(a[flag][k]<99999999)

                                                                         {

                                                                             if(dis[flag]+a[flag][k]<dis[k])

                                                                                 dis[flag]=dis[flag]+a[flag][k];

                                                                         }

                                                                     }

                                                                  }

        好啦,以上就是今天的内容了,我们下次再见吧。对了,博主比较懒,所以一般不会发完整代码的,就这个代码博主也犹豫了

天才敲的呢,不说了,我作业还没写呢,拜拜咯~

0 0
原创粉丝点击