最短路径dijkstra

         在一个无权的图中 , 若从一顶点到另一顶点存在着一条路径 , 则称该路径长度为该路径上所经过的边的数目 , 它等于该路径上的顶点数减 1 。由于从一顶点到另一顶点可能存在着多条路径 , 每条路径上所经过的边数可能不同 , 即路径长度不同 , 我们把路径长度最短 ( 即经过的边数最少 ) 的那条路径叫做 最短路径 , 其路径长度叫做最短路径长度或最短距离。
         对于带权的图 , 考虑路径上各边上的权值,则通常把一条路径上所经边的权值之和定义为该路径的 路径长度 或称 带权路径长度 。从源点到终点可能不止一条路径,把带权路径长度最短的那条路径称为最短路径 , 其路径长度 ( 权值之和 ) 称为最短路径长度或者最短距离。
        如何求从一个顶点到其余各点的最短路径? Dijkstra 提出了一种按路径长度递增的次序产生最短路径的算法。如下图:

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

Dijkstra 算法的具体步骤:
  S 为已经求得的最短路径的顶点集合, dist[i] 表示 v 0 v i 的最短路径。
(1)S={v 0 } dist[i]=cost [v 0 ][v i ]       //初始化
(2) 选择 u ,使得 dist[u]=min{dist[i] | v i 不在 S }, u 为当前求得的一条从 v 0 出发的最短路径的终点,让 S=S+{u},即S集合中加入顶点u。
(3) 修改所有不在 S 中的顶点 Vi 的最短路径长度            //这是因为集合S中新增了顶点,则需要更新U中顶点距离从v0到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
 if dist[u]+cost[u][v i ]<dist[i]
    dist[v i ]= dist[u]+cost[u][v i ]
(4) 重复步骤 (2) (3) 直到所有顶点都包含在 S 中。
如图:

S                                U                      v0 06各顶点的距离
{0}                        {1,2,3,4,5,6}          {0,4,6,6,,,}
{0,1}                      {2,3,4,5,6}            {0,4,5,6,11,,}
{0,1,2}                   {3,4,5,6}              {0,4,5,6,11,9,}
{0,1,2,3}                {4,5,6}                 {0,4,5,6,11,9,}
{0,1,2,3,5}             {4,6}                    {0,4,5,6,10,9,17}
{0,1,2,3,5,4}         {6}                        {0,4,5,6,10,9,16}
{0,1,2,3,5,4,6}       {}                         {0,4,5,6,10,9,16}
v0v1v6各顶点的最短距离分别为45610916
Dijkstra 算法的具体C语言实现:
void dijkstra(int cost[][MAXNODE],int n,int v0,int Distance[])
{
   int s[MAXNODE];
   int mindis,dis;
   int i,j,u;
   /*初始化*/
   for(i=0;i<n;i++)
   {
      Distance[i]=cost[v0][i];
      s[i]=0;
     }
   s[v0]=1   /*标记v0*/
   /*在当前还未找到最短路径的顶点集中选取具有最短距离的顶点u*/
   for(i=1;i<n;i++)
   {
       mindis=MaxCOST;
       for(j=1;j<n;j++)
       if (s[j]==0 && DIstance[j]<mindis)
        {
            u=j;
            mindis=Distance[j];
        }
       s[u]=1;    /*标记u*/
   /*修改从v0到其他顶点的最短距离*/
   for(j=1;j<n;j++)
    if (s[j]==0)
    {
       dis=Distance[u]+cost[u][j];
       Distance[j]=(Distance[j]<dis)?Distance[j]:dis;
    }
   }
}
时间复杂度有点高,o(n^2)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值