对滴,你们的博主又回来了,按照上一次博主所承诺的,今天博主和大家来聊一聊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];
}
}
}
好啦,以上就是今天的内容了,我们下次再见吧。对了,博主比较懒,所以一般不会发完整代码的,就这个代码博主也犹豫了
半天才敲的呢,不说了,我作业还没写呢,拜拜咯~