Dijkstra算法

最近由于工作需要,需要研究最佳路径选择问题.估重新复习了遍dijkstra算法,以下做个记录

 

ExpandedBlockStart.gif 代码
#include  " stdio.h "
#include 
< iostream.h >
using   namespace  std; 
#define  BIG 65535  // 无穷大

// Dijkstra算法函数,求给定顶 点到其余各点的最短路径
// 参数:邻接矩阵、顶点数、出发点的下标、结果数组、路径前一点记录 
void  Dijkstra( int  Cost[][ 5 ], int  n, int  v0, int  Distance[], int  prev[])
{
    
int  s[ 5 ];
    
int  mindis,dis;
    
int  i,j,u;
    
// 初始化
     for (i = 0 ;i < n;i ++
    {
        Distance[i]
= Cost[v0][i];
        s[i]
= 0 ;
        
if (Distance[i] == BIG)
        prev[i] 
=   - 1 ;
        
else
        prev[i] 
=  v0;
    }
    Distance[v0] 
=   0 ;
    s[v0] 
= 1 // 标记v0
    
// 在当前还未找到最短路径的顶点中,
    
// 寻找具有最短距离的顶点
     for (i = 1 ;i < n;i ++
    {
// 每循环一次,求得一个最短路径
        mindis = BIG;
        u 
=  v0;
        
for  (j = 0 ;j < n;j ++ // 求离出发点最近的顶点
         if (s[j] == 0 && Distance[j] < mindis) 
        {
            mindis
= Distance [j];
            u
= j;
        } 
//  if语句体结束,j循环结束
        s[u]  =   1 ;
        
for (j = 0 ;j < n;j ++ // 修改递增路径序列(集合)
         if (s[j] == 0 && Cost[u][j] < BIG) 
        { 
// 对还未求得最短路径的顶点
            
// 求出由最近的顶点 直达各顶点的距离
            dis = Distance[u]  + Cost[u][j];
            
//  如果新的路径更短,就替换掉原路径

            
if (Distance[j] > dis)
            {
                Distance[j] 
=  dis;
                prev[j] 
=  u;
            }
        } 
//  if 语句体结束,j循环结束
    }  //  i循环结束
}
//  输出最短路径
//  参数:路径前一点记录、出发点的下标、到达点下标、顶点数
void  PrintPrev( int  prev[], int  v0, int  vn, int  n)
{
    
int  tmp  =  vn;
    
int  i  =   1 ;
    
// 临时存路径 
     int   * tmpprv  =   new   int [n];
    
// 初始化数组 
     for ( int  ii = 0 ;ii < n;ii ++ )
    tmpprv[ii] 
=   0 ;

    
// 记录到达点下标 
    tmpprv[ 0 =  vn + 1 ;
    
// 中间点用循环记录 
     for ( int  j = 1 ;j < n;j ++ )
    {
        
if (prev[tmp]  !=   - 1 && tmp  !=   0 )
        {
            tmpprv[i] 
=  prev[tmp] + 1 ;
            tmp 
=  prev[tmp];
            i
++ ;
        }
        
else   break ;
    }

    
// 输出路径,数组逆向输出 
     for ( int  i = n - 1 ;i >= 0 ;i -- )
    {
        
if (tmpprv[i]  != 0 )
        { 
// 排除0元素 
            cout << " \tV " << tmpprv[i];
            
if (i)   // 不是最后一个输出符号 
                cout  <<   "  -->  " ;
        }
    }
}
// 主函数
int  main()
{
    
// 给出有向网的顶点数组 
     char   * Vertex[ 5 ] = { " V1 " , " V2 " , " V3 " , " V4 " , " V5 " };
    
// 给出有向网的邻接矩阵
     int  Cost[ 5 ][ 5 ] = {{ 0 , 10 ,BIG, 30 , 100 },
        {BIG,
0 , 50 ,BIG,BIG},
        {BIG,BIG,
0 ,BIG, 10 },
        {BIG,BIG,
20 , 0 , 60 },
        {BIG,BIG,BIG,BIG,
0 },
    };
    
int  Distance[ 5 ];  // 存放求得的最短路径长度
     int  prev[ 5 ];   // 存放求得的最短路径
    
// 调用Dijkstra算法函数,求顶点V1到其余各点的最短路径
    
// 参数:邻接矩阵、顶点数、出发点的下标、 结果数组
    Dijkstra(Cost, 5 , 0 ,Distance,prev);
    
for ( int  i = 0 ;i < 5 ;i ++ )
    {
        
// 输出最短路径长度
        cout  <<  Vertex[ 0 <<   " --> "   <<  Vertex[i]  <<   " \t "   << Distance[i];
        
// 输出最短路径
        PrintPrev(prev, 0 ,i, 5 );
        cout 
<< endl;
    }
    system(
" pause " );
    
return   0 ;
}

 

 

转载于:https://www.cnblogs.com/tqlin/archive/2010/04/23/1718683.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值