-
问题
对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径,按实验报告模板编写算法。
-
解析
以a为起点,设dis[i],表示从a到第i个点的最短距离。
找出一个未被标记的,dis[i]最小的节点i,然后标记节点i。
扫描节点i的所有出边(i,j,k),若d[j]>d[i]+k,则使用d[i]+k,更新d[j]。
重复直到所有节点都被标记,dis[n-1]即a到h的最短距离。 -
设计
伪代码:
void Dijkstra( ) {
for (i = 0; i <顶点个数; i++) {
min = MAX;
for (j = 0; j <顶点个数; j++) {
找到距离最近的点并标记;
}
flag[j] = 1;
for (k = 0; k <顶点个数; k++) {
if (!flag [k] && 将k作为中间点距离更近)
更新dis[i];
}
}
} -
分析
时间复杂度O(n^2) -
源码
https://github.com/woshichunchongchong/Algorithm_hw/blob/main/Dijkstra.cpp
#include
#define MAX_SIZE 100
#define MAX 100000
using namespace std;
int n=8;
int flag[MAX_SIZE];
int p[MAX_SIZE][MAX_SIZE]={{0,1,MAX,MAX,MAX,MAX,MAX,MAX}, //邻接矩阵
{MAX,0,MAX,2,MAX,MAX,MAX,MAX},
{2,MAX,0,MAX,MAX,MAX,MAX,MAX},
{MAX,MAX,1,0,MAX,8,MAX,MAX},
{MAX,MAX,MAX,2,0,MAX,2,MAX},
{MAX,MAX,MAX,MAX,2,0,MAX,MAX},
{MAX,MAX,MAX,MAX,MAX,3,0,3},
{MAX,MAX,MAX,MAX,MAX,2,MAX,0},};
int dis[MAX_SIZE];
void Dijkstra(){
int min,k;
for(int i=0;i<n-1;i++){
//找到离1号顶点最近的顶点
min=MAX;
for(int j=0;j<n;j++){
if(flag[j]==0 && dis[j]<min){
min=dis[j];
k=j;
}
}
flag[k]=1;
for(int x=0;x<n;x++){
if(p[k][x]<MAX){
if(dis[x]>dis[k]+p[k][x]){
dis[x]=dis[k]+p[k][x];
}
}
}
}
}
int main(){
for(int i=0;i<n;++i){
dis[i]=p[0][i];//a到其他点的距离
}
flag[0]=1;
for(int i=1;i<n;i++){
flag[i]=0;
}
Dijkstra();
printf("%d ",dis[n-1]);
return 0;
}