Dijkstra算法解决的是有向加权连通图中,单源节点到所有节点的最短路径问题。
即已知一个有向加权连通图G,和该图中的源节点s,求s到其他所有节点的最短路径。
由于是有向加权图,所以用邻接矩阵描述比较合适,a[n+1][n+1]用来描述该图,其中a[i][j]为i到j的目前所知的最短距离,如果没有直接路径,暂时设为NoEdge(一个很大的数)。
用一个链表L(也可以是优先队列,因为每次都要执行最小值出队操作)维护所有s能到达的、但还没确定最短路径的节点。
用一个数组p[n],维护最短路径,即p[i]为s到i的当前所知的最短路径上i的前一个节点,可能会变化,这样在算法结束后通过逆向就可以得到该完整路径:i->p[i]->p[p[i]]->...->s。
初时,所有a[s][i]!=NoEdge的节点i都插入到L中。
然后从L中找到d[s][i]最小的节点i,可以保证,此d[s][i]即为s到i的最短路径长度,由于是第一次从L中找节点,这点自然能保证。
找到i后,将i从L中删除,并令p[i]=s,则i的最短路径已经确定:s->i。
由于s->i的最短路径已经建立,那么应该考察其他点的d[j]是否会受影响。遍历所有从i能到达的点j(即a[i][j]!=NoEdge),看是否有p[j]==0(说明还没有找到从s到j的路径)或者d[i]+a[i][j]<d[j](说明新找到的路径更短),若如此,说明d[j]应该更新,更新之,并且令p[j]=i,因为在最新的s到j的最短路径中,j的上一个节点是i。如果刚才判断时p[j]==0,即s到j刚刚变为可达,就将j插入到L中。
之后再迭代,从L中选择d[i]最小的节点i,则可以确定s到i的最短路径即为d[i],因为:
1)d[i]为当前已知s到i的最短路径长度,
2)其它L中的节点j都有d[j]>d[i],因此即使有其它迂回路径,也不是最短:d[j]+a[j][i]>d[i]。
而s到i的最短路径上i的前一个节点也已经保存在p[i]中了。
然后再回到上述步骤,更新d[j]和p[j]。
直到L为空,所有节点的最短路径均已找到。