【算法系列-2】最短路径-Dijkstra 算法

来源:互联网 发布:nc软件是什么 编辑:程序博客网 时间:2024/06/10 22:08

声明:转载的,内容来自网络,自己复习用。

详细请见

http://blog.csdn.net/ahalei/article/details/22717661

【啊哈!算法】系列7:Dijkstra最短路算法

作者:啊哈磊

讲的真是图文并茂,简单易懂!!

对人家的劳动成果表示尊重!

-------------------------------------------------------【华丽的分割线】-----------------------------------------------------------------

这部分是补充的部分

【算法思想】

设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

【算法步骤】

a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。


b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。


c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。


d.重复步骤b和c直到所有顶点都包含在S中。


执行动图


严蔚敏版算法实现

#include <iostream>#include <cstdio>#define MAX 1000000using namespace std;int arcs[10][10];//邻接矩阵int D[10];//保存最短路径长度int p[10][10];//路径int final[10];//若final[i] = 1则说明 顶点vi已在集合S中int n = 0;//顶点个数int v0 = 0;//源点int v,w;void ShortestPath_DIJ(){     for (v = 0; v < n; v++) //循环 初始化     {          final[v] = 0; D[v] = arcs[v0][v];          for (w = 0; w < n; w++) p[v][w] = 0;//设空路径          if (D[v] < MAX) {p[v][v0] = 1; p[v][v] = 1;}     }     D[v0] = 0; final[v0]=0; //初始化 v0顶点属于集合S     //开始主循环 每次求得v0到某个顶点v的最短路径 并加v到集合S中     for (int i = 1; i < n; i++)     {          int min = MAX;          for (w = 0; w < n; w++)          {               //我认为的核心过程--选点               if (!final[w]) //如果w顶点在V-S中               {                    //这个过程最终选出的点 应该是选出当前V-S中与S有关联边                    //且权值最小的顶点 书上描述为 当前离V0最近的点                    if (D[w] < min) {v = w; min = D[w];}               }          }          final[v] = 1; //选出该点后加入到合集S中          for (w = 0; w < n; w++)//更新当前最短路径和距离          {               /*在此循环中 v为当前刚选入集合S中的点               则以点V为中间点 考察 d0v+dvw 是否小于 D[w] 如果小于 则更新               比如加进点 3 则若要考察 D[5] 是否要更新 就 判断 d(v0-v3) + d(v3-v5) 的和是否小于D[5]               */               if (!final[w] && (min+arcs[v][w]<D[w]))               {                    D[w] = min + arcs[v][w];                   // p[w] = p[v];                    p[w][w] = 1; //p[w] = p[v] + [w]               }          }     }}  int main(){    cin >> n;    for (int i = 0; i < n; i++)    {         for (int j = 0; j < n; j++)         {              cin >> arcs[i][j];         }    }    ShortestPath_DIJ();    for (int i = 0; i < n; i++) printf("D[%d] = %d\n",i,D[i]);    return 0;}


--2017-01-31 初四

0 0
原创粉丝点击