在有权图中,利用迪杰斯特拉(Dijkstra)算法求解最短路径:
程序如下:
#include<iostream> #include<assert.h> #include<string> #include<limits.h> #define NUM 7 using namespace std; //利用二维数组创建有向图的邻接矩阵 void CreateMatrix(int mat[NUM][NUM]); //利用迪杰斯特拉算法求解单源最短路径 void DijkstraSearch(int mat[NUM][NUM], int i, int visit[NUM], int dist[NUM], int path[NUM]); //递归输出源点到顶点i的路径 void PrintDist(int i, int path[]); int main() { //创建有向图的带有权值的邻接矩阵 int mat[NUM][NUM]; for (int i = 0; i < NUM;i++) { for (int j = 0; j < NUM;j++) { mat[i][j] = INT_MAX; } } CreateMatrix(mat); int visit[NUM] = {0}; int dist[NUM]; for (int i = 0; i < NUM;i++) { dist[i] = INT_MAX; } int path[NUM] = {0}; //利用迪杰斯特拉算法求解单源最短路径 //初始源点的dist初始化为0,path初始化为0 dist[0] = 0; path[0] = 0; DijkstraSearch(mat,0,visit,dist,path); //输出源点到各个顶点的最短路径长度以及所走路径 for (int i = 0; i < NUM;i++) { printf("从右向左,v0到v%d的路径为:",i); printf("%d ", i); PrintDist(i,path); printf("%d ", 0); printf(" 距离:%d",dist[i]); printf("\n"); } return 0; } //递归输出源点到顶点i的路径 void PrintDist(int i, int path[]) { int p = path[i]; if (p==0) { return; } else { printf("%d ",p); PrintDist(p,path); } } //利用二维数组创建有向图的邻接矩阵,带权值 void CreateMatrix(int mat[NUM][NUM]) { mat[0][1] = 2; mat[0][3] = 1; mat[1][3] = 3; mat[1][4] = 10; mat[2][0] = 4; mat[2][5] = 5; mat[3][2] = 2; mat[3][4] = 2; mat[3][5] = 8; mat[3][6] = 4; mat[4][6] = 6; mat[6][5] = 1; } //利用迪杰斯特拉算法求解单源最短路径 void DijkstraSearch(int mat[NUM][NUM], int i, int visit[NUM], int dist[NUM], int path[NUM]) { //初始化 visit[i] = 1; //dist[i] = 0; //path[i]=0; //访问与顶点i相邻接的未被访问的顶点,获取路径长度,如果小于之前路径长度则替换,并记录路径 for (int j = 0; j < NUM;j++) { if (visit[j] == 0 && mat[i][j] != INT_MAX) { if (dist[i]+mat[i][j]<dist[j]) { dist[j] = dist[i] + mat[i][j]; path[j] = i; } } } //在未被访问过的顶点中寻找路径最短的顶点 int minDist = -1; for (int m = 0;m<NUM;m++) { if (visit[m] == 0) { minDist = m; break; } } for (int k = minDist + 1; k<NUM; k++) { if (visit[k] == 0 && dist[k]<dist[minDist]) { minDist = k; } } //如果找到继续寻找到下一个顶点的最短路径(递归) if (minDist != -1) { DijkstraSearch(mat, minDist, visit, dist, path); } }
输出结果: