迪杰斯特拉(Dijkstra)最短路径算法
回顾算法思路:
该算法用于求指定顶点A到其余每个顶点的最短路径;
将顶点分为两部分S、U,S部分是已经确定最短路径的点,另一部分U是尚未确定最短路径的点,
确保目前状态X的所有路径是从集合S到U某一点的最短路径(即路径只有终点在U中,其余顶点均在S中;
1、在所有路径中选取最短的路径所对应的顶点加入到S中(该条路径已经是确定的最短路径;
2、由于S中加入了一个顶点B,更新其他路径以达到状态X
循环1、2,确保所有的点都已加入S,结束;
#include<iostream> #include<cstdlib> #include<string> using namespace std; struct Dis { string path;//存储路径 int value;//存储路径的值 bool visit;//是否加入S中 Dis() {//构造函数 visit = "false"; value = INT_MAX; path = ""; } }; struct Graph_DG { int vexnum;//顶点的数量 int arcnum;//边的数量 int **a;//存储图即每对顶点的权重 Dis *dis; }; int main() { cout << "本算法计算的是从无向图中一个指定点到其他任何一点"<< "的最短距离,以及对应的路径" << endl; Graph_DG DG; /*创建图*/ cout << "请输入顶点数和边数:"; cin >> DG.vexnum >> DG.arcnum; DG.a = new int *[DG.vexnum]; for (int i = 0; i < DG.vexnum; i++) { DG.a[i] = new int[DG.vexnum]; for (int j = 0; j < DG.vexnum; j++) { DG.a[i][j] = INT_MAX; if (i == j) DG.a[i][j] = 0; } } cout << "请输入每条边的起始点,终点和对应的权值" << endl; for (int i = 0; i < DG.arcnum; i++) { int x, y; cin >> x >> y; cin >> DG.a[x][y]; DG.a[y][x] = DG.a[x][y]; } int start; cout << "请输入该指定点:"; cin >> start; DG.dis = new Dis[DG.vexnum]; for (int i = 0; i < DG.vexnum; i++) { DG.dis[i].value = DG.a[start][i]; DG.dis[i].visit = false; DG.dis[i].path = to_string(start) + "-->" + to_string(i); } //使用迪杰斯特拉算法 int count = 1; DG.dis[start].visit = true;//将起点加入S中 while (count < DG.vexnum) { int min = INT_MAX; int temp; for (int i = 0; i < DG.vexnum; i++) { if (DG.dis[i].value <= min && DG.dis[i].visit == false) {//只要有未加入的点,就找出距离最短的点加入 min = DG.dis[i].value; temp = i; } } count++; DG.dis[temp].visit = true; //更新距离 for (int i = 0; i < DG.vexnum ; i++) { if (DG.dis[i].visit == false) { if (DG.a[temp][i] < INT_MAX && DG.dis[i].value < INT_MAX && DG.dis[temp].value + DG.a[temp][i] < DG.dis[i].value) { DG.dis[i].path = DG.dis[temp].path + "-->" + to_string(i); DG.dis[i].value = DG.dis[temp].value + DG.a[temp][i]; } } } } //打印输出 for (int i = 0; i < DG.vexnum; i++) { if(DG.dis[i].value < INT_MAX) cout <<"距离:"<< DG.dis[i].value <<"最短路径:"<< " , "<< DG.dis[i].path << endl; else cout << "距离:" << "infinite , " << "最短路径:" << DG.dis[i].path << endl; } //非内部数据类型手动释放内存 delete[] DG.dis; //二维数组释放内存的方法 for (int i = 0; i < DG.vexnum; i++) delete[] DG.a[i]; delete[] DG.a; system("pause"); return 0; }
运行结果如下: