最短路径 Dijksstra算法求最短路

1.两地之间是否有通路?
2.若存在多条通路,哪条路最短?

    

单源最短路径
   Single-Source Shortest Path
                                 (Dijkstra算法)
   负权边的有向图单源最短有路径
    Bellman-Ford算法

 

所有顶点对间的最短路径问题
   All-Pairs Shortest paths        Floyd算法)
问题: 带权有向图G(E,V), 找出从给定源顶点s其它顶点v的权最小路径。
“最短路径” = 最小权

 

 在日常生活中,我们如果需要常常往返A地区和B地区之间,我们最希望知道的可能是从A地区到B地区间的众多路径中,那一条路径的路途最短。最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。确定起点的最短路径问题:即已知起始结点,求最短路径的问题。

 Dijkstra算法

  Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

如下图:

 

贪心算法:
  基于以下原理:若顶点序列{Vs,V1,…,Vn} 是从Vs到Vn的最短路,则序列 {Vs,V1,…,Vn-1} 必为从Vs到Vn-1的最短路。
基本思想:
   设置一个顶点集S,不断做贪心选择扩充这个集合。
  一个顶点属于S当且仅当从源到该顶点最短路径长度已知。
 
 
图中从v0到其余各顶点之间的最短路径:
v0      v1    
v0     v2   (v0,v2)               10
 v0    v3   (v0,v4,v3)          50
 v0    v4   (v0,v4)                30
 v0    v5   (v0,v4,v3,v5)     60
 
  初始时,S仅包含源s,
 特殊路径:
  从源到G中某一顶点u且中间只经过S中顶点的路称为从源到u的特殊路径
 算法每次从V-S中取出具有最短特殊路径
   长度的顶点u加入S中。
算法思想:
   按路径长度递增序产生各顶点最短路径
 
 
 
用到的变量:
 
int  G[maxnum][maxnum]; //邻接矩阵,距离无限远用9999表示
 
int  dist[maxnum]; //存放各个顶点到源点的寻短路径;
 
bool  visit[maxnum] ;  //标志该定点是否被访问,初始化wei 0
 
int last;//表示当前所走路径最后一个节点
 
利用贪心算法,首先从原点出发,初始化dist[maxnum]; 假如源点v0,顶点数目6  (v0,v1,v2,v3,v4,v5);
 
for i=0 to 5 ,dist[i]=G[0][i];   
 然后dist[0] = 0;//到本身距离为0, 再标记V0点, visit[0] = 1;//以访问v0点,
此时dist[5]={0,9999,30,9999,30,100};  visit[]={1,0,0,0,0,0};  last = 0;//v0点为当前路径最后一个
 
然后for循环,寻找从源点到其他店的最小距离,并且该点未被访问,
 
int min = 9999;
for(j=0;j<n;j++) 
{
    if(!visit[j] && min< G[v0][j])
   {
         min = G[last][j];
                    last = j;
   }
}

 
得到 last=2;//将v2加入当前路径 ,    visit[last] = 1; 
visit[] = {1,0,1,0,0,0}
 
然后将dist[]数组更新。, 更新为V0到各个点的最短路径
然后循环,直到所有结点都被访问;
 
for(j=0;j<n;j++)
 { 
         if(!visit[j] && G[last][j]!=99999)
          { 
                   int newdist = dist[last] + G[last][j];
                   if(newdist < dist[j])
                        { 
                                dist[j] = newdist;
                                     prev[j] = last;
                         } 
            } 
 }
 

 
 
 
 
 
练习:  Hdu 2544   hdu1874
 
#include <iostream>

using namespace std;

void Dijkstra(int n,int v,int *dist,int *prev,int G[102][102]) 
{
    bool visit[102];//存放顶点是否被访问
    int i,j;
    for(i=1; i<=n; i++)
    {
        visit[i] = 0;
        dist[i] = G[v][i];
        if(dist[i]== 99999) prev[i] = 0;
        else prev[i] = v;    
    } 
    
    dist[v] = 0; 
    visit[v] = 1;
    
     for(i=2;i<=n;i++)//访问剩下的点
     {
        int last = v;
        int min = 99999; 
        //寻找本行未使用点j的dist[j]最小值
        for(j=1;j<=n;j++)
        {
            if(!visit[j]&& min>dist[j])    
            {
                
                min = dist[j];
                last = j;//距离最小点的号码 
            }
        }    
        
        visit[last] = 1;//访问该距离最小点
        
        //将dist[]刷新
        for(j=1;j<=n;j++)
        {
            if(!visit[j] && G[last][j]!=99999)
            {
                int newdist = dist[last] + G[last][j];
                
                if(newdist < dist[j])
                {
                    dist[j] = newdist;
                    prev[j] = last;    
                }
            }
    //        printf("%d ",dist[j]);    
        }    
    //    printf("\n");
    } 
}


int main()
{

    int i,j,a,b,c;
    int dist[102];  
    int prev[102];  //记录当前点的前一个结点
    int G[102][102];
    int vnum,m; 
    
    while(scanf("%d%d",&vnum,&m),m&&vnum)
    {    
        
        for(i=1;i<=vnum;i++)
            for(j=1;j<=vnum;j++)
                G[i][j] = 99999;
    
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            G[a][b] = G[b][a] = c;    
        }
        
        for(i=1;i<=vnum;i++)
            dist[i] = 99999; //原点到各个点距离初始化
        
    //    for(i=1;i<=vnum;i++) //输出创建的邻接矩阵 
//        {
//            for(j=1;j<=vnum;j++)
//                printf("%4d",G[i][j]);
//            printf("\n");
//        } 

        Dijkstra(vnum,1,dist,prev,G);
        printf("%d\n",dist[vnum]);
    
    }
    
    return 0;    
}