Dijkstra---单源最短路径

                                              Dijkstra

 


【基本思想】:

总述:从一个最初只含有源点的有向子网开始,逐步扩大到由单源最短路径构成的有向子网为止。

最初只含有源点的有向子网称为入选子网。入选子网以外的顶点组成候选点集

@ 候选点集的一个顶点被加入到入选子网需满足条件:从源点到该顶点的最短带权路径长度已知,而且除该顶点外,路径的其他顶点都属于入选子网。

1. 开始时,入选子网只含有源点,从源点到源点的最短带权路径长度为0,候选点集的每个顶点都对应这样一条路径:是从源点到该顶点且中间只经过入选子网顶点的路径中最短的一条,这条路径称为候选路径。候选路径集合称为候选路径集。

2. 在候选路径集中选择一条最短的,把终点和相应的边加入到入选子网,入选子网扩大了,候选点集缩小了,这时的候选路径集需要更新,然后再选出最短的,加入到入选子网。

依此类推,直到入选子网顶点集等于网络的顶点集为止。

【实例讲解】:

Dijkstra---单源最短路径_第1张图片

准备:首先将V0加入入选子网,遍集为空集,其他顶点构成候选点集。

(步骤1)将所有V0->其他顶点的路径填写好,无路径写无穷。找出值最小的路径(V0->V2,10),然后将V2加入入选子网。

(步骤2)更新候选路径集。例如V0->V3原来的最短路径长度为无穷,当借助入选子网中的V2后,最短路径更新为V0->V2->V3,长度为(V0,V2)+(V2,V3)=10+50=60。更新时注意:若借助入选子网中的顶点最短路径长度更小就更新。(V0,V1),(V0,V4)(V0,V5)借助V2,最短路径长度没有改变,就不更新。更新后选择最小的(V0,V4,30),将V4加入入选子网。

(步骤3)更新候选路径集。更新时注意:若剩余候选点V1,V3,V5借助入选子网中除源点外的顶点{V2和V4}最短路径可以变得更小就更新最短路径。例如V0->V5原来的最短路径为长度100,借助V4后可以变为(V0,V4)+(V4,V5)=30+60=90,因此更新。最后又是选取最短的路径长度(V0-V4-V3)50,并将V3加入入选子网。

,,,,,直到所有顶点全部加入到入选子网为止,算法结束

【完整代码】:

#include
#include 
#include
#define M 100
#define N 100
using namespace std;
typedef struct node
{
    int matrix[N][M];      //邻接矩阵 
    int n;                 //顶点数 
    int e;                 //边数 
}MGraph; 
void DijkstraPath(MGraph G,int *dist,int *path,int v0)//v0表示源顶点 
{
    int i,j,k;
    bool *visited=(bool *)malloc(sizeof(bool)*G.n); 
    //初始化 : 
    for(i=0;i0&&i!=v0)
        {
            dist[i]=G.matrix[v0][i];//说明V0与i之间有路径,并把最短路径设为原始距离	 
            path[i]=v0;     //path记录最短路径上从v0到i需要经过的前一个顶点 
        }
        else
        {
            dist[i]=INT_MAX;    //若i与v0不相邻,则权值置为无穷大 
            path[i]=-1;
        }
        visited[i]=false;//初始化每个节点对应的访问标记。false代表未访问过。 
        path[v0]=v0;
        dist[v0]=0;//源顶点到本身距离为0 
    }
    //V0是源点,从它出发,做访问标记 
    visited[v0]=true;
    for(i=1;i0 && min+G.matrix[u][k]k 的前一个点u 
            }
        }        
    }    
}

void showPath(int *path,int v,int v0)   //打印最短路径上的各个顶点 
{
	cout<<"源点 "<"<<"顶点 "< s;
    int u=v;
    while(u!=v0)
    { //不断把path保存的v-v0的路径 保存到栈中,再逐个弹出就实现了v0-v的路径输出 
        s.push(u);
        u=path[u];
    }
    s.push(u);//此时的v已经与源点v0相等 
    while(!s.empty())
    {
        cout<end,权值为w
        MGraph G;
        int v0;
      //多组测试案例  
    while(cin>>n>>e && e!=0)
    {   
	    int *dist=(int *)malloc(sizeof(int)*n);//dist[i]表示 vo->i 的最短路径长度 
        int *path=(int *)malloc(sizeof(int)*n);//path[v]=u表示v0->v的最短路径中,先经过u再经过v; 
        for(i=0;i>start>>end>>w;
            G.matrix[start][end]=w;
        }
        cin>>v0;        //输入源顶点 
        DijkstraPath(G,dist,path,v0);
        for(i=0;i

【Test+运行结果】:

Dijkstra---单源最短路径_第2张图片

 

【正经致谢】:

Dijkstra---单源最短路径_第3张图片

 

你可能感兴趣的:(图,贪心,数据结构,Dijkstra,最短路径)