最短路径之Dijkstra算法
(一)Dijkstra算法
单源最短路径:就是从某一个顶点出发,到图中任意顶点之间的最短路径;
【算法概述】:Dijkstra算法适用于解决单源最短路径的问题。即:从源点到任意指定顶点之间的最短距离的问题;但Dijkstra算法要求所有边的权值非负。看过Prime算法的同学都知道,Dijkstra算法与Prime算法很相似,不同的就是dis数组的更新方式。Dijkstra算法用邻接矩阵存图比较方便。
【算法思想】:先用一个数组记录从源点到图中个顶点直接相连的距离,如果不直接连,就记录为无穷大,然后通过对该数组的更新,使得dis[x]表示从源点到x的最短路径;
1.1 初始化
用邻接矩阵来存图,先进行初始化,自己到自己的距离初始化为0,到另外的顶点的距离初始化为无穷大。并将标记数组都置为0,表示所有顶点都未访问;
void init(){
for(int i=0;i<nodeNum;i++){
for(int j=0;j<nodeNum;j++){
if(i==j)
matrix[i][j]=0;
else
matrix[i][j]=INF;
}
}
memset(visited,0,sizeof(visited));
}
1.2 Dijkstra主体
参数st表示源点,此题是0
第一步:先用min_distance数组储存与0直接相连的顶点之间的距离。并标记0号顶点;然后用一个while死循环来变量所有顶点,最坏的情况就是遍历所有顶点。
第二步:就是在当前的min_distance数组里找一个顶点没有访问过且距离源点最近的点,记录它的顶点下标;
第三步:更新min_distance数组:如果x顶点没有被访问,并且0到x顶点的距离(直接或间接)大于上面min_distance数组最小值加上点p到x点的距离,就对min_distance数组更新: min_distance[x] = min + matrix[p][x];(可以理解为:从源点直接到某点的距离大于间接到某点的距离)
第四步:重复上面的第二步和第三步;
图示:
第一步:此时的dis数组:0 5 2 7;并标记源点0;此时的vis数组:1 0 0 0
void Dijkstra(int start){
//第一个结点进入,标记已走过
for(int i=0;i<nodeNum;i++){
min_distance[i]=matrix[start][i];
}
/*for(int i=0;i<nodeNum;i++){
cout<<min_distance[i];
}*/
visited[start]=true;//表示start结点已经走过
while(true){
//找到距离这个结点最近的节点的坐标
int min=INF;
int index=-1;
for(int i=0;i<nodeNum;i++){
if(visited[i]==false && min_distance[i]<min){
min=min_distance[i];//从起点到index的最小距离
index=i;
}
}
visited[index]=true;//标记已经访问
if(index==-1)//此时所有的节点都已经访问过了
bre