参考:https://wangkuiwu.github.io/2013/04/14/dijkstra-cplus

Dijkstra算法介绍

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。

它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

算法基本思想

通过 Dijkstra 计算图 G 中的最短路径时,需要指定起点 s(即从顶点 s 开始计算)。

此外,还需要引进两个集合 S 和 U。S 的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而 U 则是记录还未求出最短路径的顶点(以及该顶点到起点 s 的距离)。

起初是,S 中只有顶点 s,U 中是除 s 之外的顶点,并且 U 中顶点的路径是“起点 s 到该顶点顶点路径”。然后,从 U 中找出路径最短的顶点,并将其加入到 S 中;接着,更新 U 中的顶点和顶点对应的路径。然后,再从 U 中找出路径最短的顶点,并将其加入到 S 中;接着,更新 U 中的顶点和顶点对应的路径。… 一直重复这样的工作,直到遍历完所有顶点。

操作步骤

1)初始时,S 只包含起点 s。U 包含除 s 外的其他顶点,且 U 中顶点的距离为“起点 s 到该顶点的距离”。例如,U 中顶点 v 的距离为 (s, v) 的长度,然后 s 和 v 不相邻,则 v 的距离为 ∞。

2)从 U 中选出“距离最短的顶点 k”,并将顶点 k 加入到 S 中,同时,从 U 中移除顶点 k。

3)更新 U 中各个顶点到起点 s 的距离。之所以更新 U 中顶点的距离,是由于上一步中确定了 k 是求出最短路径的顶点,从而可以利用 k 来更新其它顶点的距离。例如,(s, v) 的距离可能大于 (s, k)+(k, v) 的距离。

4)重复步骤 (2) 和 (3),直到遍历完所有顶点。

单纯的看上面的理论可能比较难以理解,下面通过实例来对该算法进行说明。

Dijkstra算法图解

图 G4

还是以上面的图 G4 为例,来对迪杰斯特拉进行算法演示(以第 4 个顶点 D 为起点)。

过程说明

初始状态:S 是已计算出最短路径的顶点集合,U 是未计算出最短路径的顶点的集合。

第一步:将顶点 D 加入到 S 中并从 U 中移除,此时 S={ D(0) },此时最短路径 D->D = 0,然后以 D 为中间点,更新 U 中各个顶点到 D 的距离。其中,D->C = 3,D->E = 4,所以:U={ A(∞), B(∞), C(3), E(4), F(∞), G(∞) }。

第二步:上一步之后,U 中距离起点 D 距离最短的是 C,将顶点 C 加入到 S 中并从 U 中移除,此时 S={ D(0), C(3) },此时最短路径 D->D = 0,D->C = 3,然后以 C 为中间点,更新 U 中各个顶点到 D 的距离。其中,B->C->D = 13,F->C->D = 9,E->C->D = 8 >= 4 不做更新,所以:U={ A(∞), B(13), E(4), F(9), G(∞) }。

第三步:上一步之后,U 中距离起点 D 距离最短的是 E,将顶点 E 加入到 S 中并从 U 中移除,此时 S={ D(0), C(3), E(4) },此时最短路径 D->D = 0,D->C = 3,D->E = 4,然后以 E 为中间点,更新 U 中各个顶点到 D 的距离。其中,F->E->D = 6,G->E->D = 12,所以:U={ A(∞), B(13), F(6), G(12) }。

第四步:上一步之后,U 中距离起点 D 距离最短的是 F,将顶点 F 加入到 S 中并从 U 中移除,此时 S={ D(0), C(3), E(4), F(6) },此时最短路径 D->D = 0,D->C = 3,D->E = 4,D->F = 6,然后以 F 为中间点,更新 U 中各个顶点到 D 的距离。其中,A->F->D = 22,G->F->D = 15 >= 12 不做更新,B->F->D = 13 >= 13不做更新,所以:U={ A(22), B(13), G(12) }。

第五步:上一步之后,U 中距离起点 D 距离最短的是 G,将顶点 G 加入到 S 中并从 U 中移除,此时 S={ D(0), C(3), E(4), F(6), G(12) },此时最短路径 D->D = 0,D->C = 3,D->E = 4,D->F = 6,D->G = 12,然后以 G 为中间点,更新 U 中各个顶点到 D 的距离。其中,A->G->D = 26 >= 22 不做更新,B->G->D = ∞ >= 13 不做更新,所以:U={ A(22), B(13) }。

第六步:上一步之后,U 中距离起点 D 距离最短的是 B,将顶点 B 加入到 S 中并从 U 中移除,此时 S={ D(0), C(3), E(4), F(6), G(12), B(13) },此时最短路径 D->D = 0,D->C = 3,D->E = 4,D->F = 6,D->G = 12,B->D = 13,然后以 B 为中间点,更新 U 中各个顶点到 D 的距离。其中,A->B->D = 25 >= 22 不做更新,所以:U={ A(22) }。

第六步:上一步之后,U 中距离起点 D 距离最短的是 A,将顶点 A 加入到 S 中并从 U 中移除,此时 S={ D(0), C(3), E(4), F(6), G(12), B(13), A{22} },此时最短路径 D->D = 0,D->C = 3,D->E = 4,D->F = 6,D->G = 12,B->D = 13,A->D = 22,然后以 B 为中间点,更新 U 中各个顶点到 D 的距离。这时候因为集合 U 已经为空,所以起点 D 到各个顶点的最短距离就计算出来了:A(22), B(13), C(3), D(0), E(4), F(6), G(12)

Dijkstra算法实现

图的邻接矩阵实现Kruskal算法

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;#define MAX 100
#define INF (~(0x1 << 31)) //无穷大(0x7FFFFFFF)const int VEXNUM = 7;struct EData
{char start; //边的起点char end;   //边的终点int weight; //边的权重EData() {}EData(char s, char e, int w) : start(s), end(e), weight(w) {}
};class MatrixUDG
{private:char mVexs[MAX];       //顶点集合,如:{'A', 'B', 'C', 'D', 'E', 'F', 'G'};int mVexNum;           //顶点数,如:7int mEdgNum;           //边数int mMatrix[MAX][MAX]; //邻接矩阵
public://创建图(手动输入)MatrixUDG();//创建图(用提供的矩阵)MatrixUDG(char *vexs, int vNum, int matrix[][VEXNUM]);~MatrixUDG();//打印邻接表void print();//Dijkstra最短路径算法void Dijkstra(int vstart, int vexs[], int dist[]);private://输入一个合法字母char readChar();//获得一个字母在顶点数组的下标int getPosition(char ch);//返回顶点v的第一个邻接顶点的索引,失败返回-1int firstVertex(int v);//范围顶点v相对于w的下一个邻接顶点的索引,失败返回-1//比如: A和C, D, E有连接,则A相对于C的下一个结点为D,即返回D的索引int nextVertex(int v, int w);//获取图中的边EData *getEdge();//对边按照权值从小到大进行排序void sortEdges(EData *edges, int eNum);//获取i的终点int getEnd(int *vEnds, int i);
};MatrixUDG::MatrixUDG()
{char c1, c2;int p1, p2;int i, j;int weight;cout << "输入顶点数:";cin >> mVexNum;cout << "输入边数:";cin >> mEdgNum;if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))){cout << "输入有误!" << endl;return;}//初始化顶点for (i = 0; i < mVexNum; ++i){cout << "vertex(" << i << "):";mVexs[i] = readChar();}//初始化边的权值for (i = 0; i < mVexNum; ++i){for (j = 0; j < mVexNum; ++j){if (i == j)mMatrix[i][j] = 0;elsemMatrix[i][j] = INF;}}//初始化边的权值,根据用户输入进行初始化for (i = 0; i < mEdgNum; ++i){cout << "edge(" << i << "):";c1 = readChar();c2 = readChar();cin >> weight;p1 = getPosition(c1);p2 = getPosition(c2);if (p1 == -1 || p2 == -1){cout << "输入的边错误!" << endl;return;}mMatrix[p1][p2] = weight;mMatrix[p2][p1] = weight;}
}MatrixUDG::MatrixUDG(char *vexs, int vNum, int matrix[][VEXNUM])
{if (!vexs || !*matrix)return;int i, j;mVexNum = vNum;//初始化顶点for (i = 0; i < mVexNum; ++i)mVexs[i] = vexs[i];//初始化边for (i = 0; i < mVexNum; ++i){for (j = 0; j < mVexNum; ++j){mMatrix[i][j] = matrix[i][j];}}//统计边的数目for (i = 0; i < mVexNum; ++i){for (j = 0; j < mVexNum; ++j){if (i != j && mMatrix[i][j] != INF){++mEdgNum;}}}mEdgNum /= 2;
}MatrixUDG::~MatrixUDG()
{}int MatrixUDG::getPosition(char ch)
{for (int i = 0; i < mVexNum; ++i){if (mVexs[i] == ch)return i;}return -1;
}char MatrixUDG::readChar()
{char ch;do{cin >> ch;} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));return ch;
}/*
返回顶点v的第一个邻接顶点的索引,失败返回-1
*/
int MatrixUDG::firstVertex(int v)
{if (v < 0 || v > (mVexNum - 1))return -1;for (int i = 0; i < mVexNum; ++i){if (mMatrix[v][i] != 0 && mMatrix[v][i] != INF)return i;}return -1;
}
/*
返回顶点v相对于w的下一个邻接顶点的索引,失败则返回-1
比如:A和C,D,E有连接,则A相对于C的下一个结点为D,即返回D的索引
*/
int MatrixUDG::nextVertex(int v, int w)
{if (v < 0 || v > (mVexNum - 1) || w < 0 || w > (mVexNum - 1))return -1;for (int i = w + 1; i < mVexNum; ++i){if (mMatrix[v][i] != 0 && mMatrix[v][i] != INF)return i;}return -1;
}//获取图中的边
EData *MatrixUDG::getEdge()
{int i, j;int index = 0;EData *edges = new EData[mEdgNum];for (i = 0; i < mVexNum; ++i){for (j = i + 1; j < mVexNum; ++j){if (mMatrix[i][j] != INF){edges[index].start = mVexs[i];edges[index].end = mVexs[j];edges[index].weight = mMatrix[i][j];++index;}}}return edges;
}//对边按照权值大小进行排序(由小到大)
void MatrixUDG::sortEdges(EData *edges, int eNum)
{//直接调用STL排序std::sort(edges, edges + eNum, [](EData &edge1, EData &edge2) -> bool{ return edge1.weight < edge2.weight; });
}int MatrixUDG::getEnd(int *vEnds, int i)
{//相当于并查集的操作while (vEnds[i] != 0){i = vEnds[i];}return i;
}/*
* Dijkstra最短路径算法,即统计图中顶点vstart到其他各个顶点的最短路径
* vstart: 起始顶点
* prev: 前驱顶点数组,prev[i]的值是顶点vstart到顶点i的最短路径所经历的全部顶点中,位于顶点i之前的那个顶点
* dist: 存储最短路径的结果数组,dist[i]是顶点vstart到顶点i的最短路径的长度
*/
void MatrixUDG::Dijkstra(int vstart, int prev[], int dist[])
{int i, j;int k;int min;int tmp;int flag[MAX];//初始化for (i = 0; i < mVexNum; ++i){flag[i] = 0;                  //顶点i的最短路径还没获取到prev[i] = 0;                  //顶点i的前驱顶点为0dist[i] = mMatrix[vstart][i]; //顶点i的最短路径为顶点vs到顶点i的权}//对顶点vstart自身进行初始化flag[vstart] = 1;dist[vstart] = 0;//遍历mVexNum-1次,每次找出一个顶点的最短路径for (i = 0; i < mVexNum; ++i){//寻找当前最小路径,在未获取最短路径的顶点中,寻找离vstart最近的顶点kmin = INF;for (j = 0; j < mVexNum; ++j){if (flag[j] == 0 && dist[j] < min){min = dist[j];k = j;}}//标记顶点k位已经获取到最短路径flag[k] = 1;// 修正当前最短路径和前驱顶点,即当已经得出顶点k的最短路径之后,更新未获取最短路径的顶点的最短路径和前驱顶点for (j = 0; j < mVexNum; ++j){tmp = (mMatrix[k][j] == INF ? INF : (min + mMatrix[k][j]));if (flag[j] == 0 && (tmp < dist[j])){dist[j] = tmp;prev[j] = k;}}}//打印Dijkstra最短路径的结果cout << "Dijkstra(" << mVexs[vstart] << "):" << endl;for (i = 0; i < mVexNum; ++i){cout << "最短路径(" << mVexs[vstart] << ", " << mVexs[i] << ")=" << dist[i] << endl;}
}void MatrixUDG::print()
{for (int i = 0; i < mVexNum; ++i){for (int j = 0; j < mVexNum; ++j){if (mMatrix[i][j] == INF){cout << "INF"<< "\t";}else{cout << mMatrix[i][j] << "\t";}}cout << endl;}
}int main()
{char vexs[VEXNUM] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int vNum = sizeof(vexs) / sizeof(vexs[0]);int matrix[][VEXNUM] = {{0, 12, INF, INF, INF, 16, 14},{12, 0, 10, INF, INF, 7, INF},{INF, 10, 0, 3, 5, 6, INF},{INF, INF, 3, 0, 4, INF, INF},{INF, INF, 5, 4, 0, 2, 8},{16, 7, 6, INF, 2, 0, 9},{14, INF, INF, INF, 8, 9, 0}};// 1. 根据提供的数据生成MatrixUDG mudg(vexs, vNum, matrix);mudg.print(); //打印图int prev[MAX] = {0};int dist[MAX] = {0};//Dijkstra算法获得第四个顶点到它各个顶点的最短距离mudg.Dijkstra(3, prev, dist);//2. 手动生成// MatrixUDG mudg1;// mudg1.print();
}

运行结果:

$ ./test
0       12      INF     INF     INF     16      14
12      0       10      INF     INF     7       INF
INF     10      0       3       5       6       INF
INF     INF     3       0       4       INF     INF
INF     INF     5       4       0       2       8
16      7       6       INF     2       0       9
14      INF     INF     INF     8       9       0
Dijkstra(D):
最短路径(D, A)=22
最短路径(D, B)=13
最短路径(D, C)=3
最短路径(D, D)=0
最短路径(D, E)=4
最短路径(D, F)=6
最短路径(D, G)=12

图的邻接表实现Kruskal算法

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;#define MAX 100
#define INF (~(0x1 << 31)) //无穷大(0x7FFFFFFF)const int VEXNUM = 7;#define MAX 100
#define INF (~(0x1 << 31)) //最大值struct EData
{char start; //边的起点char end;   //边的终点int weight; //边的权重EData() {}EData(char s, char e, int w) : start(s), end(e), weight(w) {}
};class ListUDG
{private://每一条边struct ENode{int iVex = 0;           //指向的顶点的位置int weight = 0;         //该边的权ENode *nextEdge = NULL; //指向顶点的下一条边的指针};//数组中存储的顶点struct VNode{char data;ENode *firstEdge = NULL; //指向第一条该顶点的边};private:int mVexNum;      //图的顶点数目int mEdgeNum;     //图的边的数目VNode mVexs[MAX]; //存储顶点
public://创建邻接表对应的图(自己收入)ListUDG();//创建邻接表对应的图(用已提供的数据)ListUDG(char *vexs, int vNum, EData *edges[], int eNum);~ListUDG();//打印邻接表void print();//Dijkstra最短路径算法void Dijkstra(int vstart, int vexs[], int dist[]);private://读取一个合法的输入字符char readChar();//返回字符ch在的位置int getPosition(char ch);//将node结点链接到list的最后void linkLast(ENode *list, ENode *node);//获取边<start, end>的权值,若start和end不是连通的,则返回无穷大int getWeight(int start, int end);//获取图中的边EData *getEdges();//对边按照权值从小到大进行排序void sortEdges(EData *edges, int eNum);//获取i的终点int getEnd(int *vEnds, int i);
};ListUDG::ListUDG()
{char c1, c2;int p1, p2;ENode *node1, *node2;int weight;cout << "输入顶点数:";cin >> mVexNum;cout << "输入边数:";cin >> mEdgeNum;if (mVexNum > MAX || mEdgeNum > MAX || mVexNum < 1 || mEdgeNum < 1 || (mEdgeNum > (mVexNum * (mVexNum - 1)))){cout << "输入有误!" << endl;return;}//初始化邻接表的顶点for (int i = 0; i < mVexNum; ++i){cout << "vertex(" << i << "):";mVexs[i].data = readChar();mVexs[i].firstEdge = NULL;}//初始化邻接表的边for (int j = 0; j < mEdgeNum; ++j){cout << "edge(" << j << "):";c1 = readChar();c2 = readChar();cin >> weight;p1 = getPosition(c1);p2 = getPosition(c2);if (p1 == -1 || p2 == -1){cout << "输入的边有错误!" << endl;return;}//初始化node1node1 = new ENode();node1->iVex = p2;node1->weight = weight;//将node1链接到p1所在链表的末尾if (mVexs[p1].firstEdge == NULL)mVexs[p1].firstEdge = node1;elselinkLast(mVexs[p1].firstEdge, node1);//初始化node2node2 = new ENode();node2->iVex = p1;node2->weight = weight;//将node2链接到p2所在链表的末尾if (mVexs[p2].firstEdge == NULL)mVexs[p2].firstEdge = node2;elselinkLast(mVexs[p2].firstEdge, node2);}
}ListUDG::ListUDG(char *vexs, int vNum, EData *edges[], int eNum)
{if (vNum > MAX || eNum > MAX)return;char c1, c2;int p1, p2;ENode *node1, *node2;int weight;//初始化顶点数和边数mVexNum = vNum;mEdgeNum = eNum;//初始化邻接表的顶点for (int i = 0; i < mVexNum; ++i){mVexs[i].data = vexs[i];mVexs[i].firstEdge = NULL;}//初始化邻接表的边for (int j = 0; j < mEdgeNum; ++j){//读取边的起始顶点和结束顶点c1 = edges[j]->start;c2 = edges[j]->end;weight = edges[j]->weight;p1 = getPosition(c1);p2 = getPosition(c2);if (p1 == -1 || p2 == -1){cout << "输入的边有错误!" << endl;return;}//初始化node1node1 = new ENode();node1->iVex = p2;node1->weight = weight;//将node1链接到p1所在的链表末尾if (mVexs[p1].firstEdge == NULL)mVexs[p1].firstEdge = node1;elselinkLast(mVexs[p1].firstEdge, node1);//初始化node2node2 = new ENode();node2->iVex = p1;node2->weight = weight;//将node2链接到p2所在链表末尾if (mVexs[p2].firstEdge == NULL)mVexs[p2].firstEdge = node2;elselinkLast(mVexs[p2].firstEdge, node2);}
}ListUDG::~ListUDG()
{}void ListUDG::linkLast(ENode *list, ENode *node)
{ENode *p = list;while (p->nextEdge)p = p->nextEdge;p->nextEdge = node;
}int ListUDG::getPosition(char ch)
{for (int i = 0; i < mVexNum; ++i){if (mVexs[i].data == ch)return i;}return -1;
}char ListUDG::readChar()
{char ch;do{cin >> ch;} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));return ch;
}int ListUDG::getWeight(int start, int end)
{if (start == end)return 0;ENode *node = mVexs[start].firstEdge;while (node != NULL){if (end == node->iVex){return node->weight;}node = node->nextEdge;}return INF;
}//获得图中的边
EData *ListUDG::getEdges()
{int i;int index = 0;ENode *node = NULL;EData *edges = new EData[mEdgeNum];for (i = 0; i < mVexNum; ++i){node = mVexs[i].firstEdge;while (node != NULL){if (node->iVex > i){edges[index].start = mVexs[i].data;edges[index].end = mVexs[node->iVex].data;edges[index].weight = node->weight;++index;}node = node->nextEdge;}}return edges;
}//对边按照权值大小进行排序(由小到大)
void ListUDG::sortEdges(EData *edges, int eNum)
{if (!edges)return;//直接调用STL排序std::sort(edges, edges + eNum, [](EData &edge1, EData &edge2) -> bool{ return edge1.weight < edge2.weight; });
}int ListUDG::getEnd(int *vEnds, int i)
{//相当于并查集的操作while (vEnds[i] != 0){i = vEnds[i];}return i;
}/*
* Dijkstra最短路径算法,即统计图中顶点vstart到其他各个顶点的最短路径
* vstart: 起始顶点
* prev: 前驱顶点数组,prev[i]的值是顶点vstart到顶点i的最短路径所经历的全部顶点中,位于顶点i之前的那个顶点
* dist: 存储最短路径的结果数组,dist[i]是顶点vstart到顶点i的最短路径的长度
*/
void ListUDG::Dijkstra(int vstart, int prev[], int dist[])
{int i, j;int k;int min;int tmp;int flag[MAX]; // flag[i]=1表示顶点vstart到顶点i的最短路径已成功获取//初始化for (i = 0; i < mVexNum; ++i){flag[i] = 0;                    //顶点i的最短路径还没获取到prev[i] = 0;                    //顶点i的前驱顶点为0dist[i] = getWeight(vstart, i); //顶点i的最短路径为顶点vs到顶点i的权}//对顶点vstart自身进行初始化flag[vstart] = 1;dist[vstart] = 0;//遍历mVexNum-1次,每次找出一个顶点的最短路径for (i = 0; i < mVexNum; ++i){//寻找当前最小路径,在未获取最短路径的顶点中,寻找离vstart最近的顶点kmin = INF;for (j = 0; j < mVexNum; ++j){if (flag[j] == 0 && dist[j] < min){min = dist[j];k = j;}}//标记顶点k位已经获取到最短路径flag[k] = 1;// 修正当前最短路径和前驱顶点,即当已经得出顶点k的最短路径之后,更新未获取最短路径的顶点的最短路径和前驱顶点for (j = 0; j < mVexNum; ++j){tmp = getWeight(k, j);tmp = (tmp == INF ? INF : (min + tmp));if (flag[j] == 0 && (tmp < dist[j])){dist[j] = tmp;prev[j] = k;}}}//打印Dijkstra最短路径的结果cout << "Dijkstra(" << mVexs[vstart].data << "):" << endl;for (i = 0; i < mVexNum; ++i){cout << "最短路径(" << mVexs[vstart].data << ", " << mVexs[i].data << ")=" << dist[i] << endl;}
}void ListUDG::print()
{ENode *node;for (int i = 0; i < mVexNum; ++i){cout << i << "(" << mVexs[i].data << "):";node = mVexs[i].firstEdge;while (node != NULL){cout << node->iVex << "(" << mVexs[node->iVex].data << ")";node = node->nextEdge;}cout << endl;}
}int main(int argc, char **argv)
{char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};EData *edges[] = {new EData('A', 'B', 12),new EData('A', 'F', 16),new EData('A', 'G', 14),new EData('B', 'C', 10),new EData('B', 'F', 7),new EData('C', 'D', 3),new EData('C', 'E', 5),new EData('C', 'F', 6),new EData('D', 'E', 4),new EData('E', 'F', 2),new EData('E', 'G', 8),new EData('F', 'G', 9),};int vNum = sizeof(vexs) / sizeof(vexs[0]);int eNum = sizeof(edges) / sizeof(edges[0]);//1. 根据提供的数据生成ListUDG ludg(vexs, vNum, edges, eNum);ludg.print();int prev[MAX] = {0};int dist[MAX] = {0};//Dijkstra算法获得第四个顶点到它各个顶点的最短距离ludg.Dijkstra(3, prev, dist);//2. 手动输入// ListUDG ludg;// ludg.print();return 0;
}

运行结果:

$ ./test
0(A):1(B)5(F)6(G)
1(B):0(A)2(C)5(F)
2(C):1(B)3(D)4(E)5(F)
3(D):2(C)4(E)
4(E):2(C)3(D)5(F)6(G)
5(F):0(A)1(B)2(C)4(E)6(G)
6(G):0(A)4(E)5(F)
Dijkstra(D):
最短路径(D, A)=22
最短路径(D, B)=13
最短路径(D, C)=3
最短路径(D, D)=0
最短路径(D, E)=4
最短路径(D, F)=6
最短路径(D, G)=12

图的最短路径之Dijkstra算法相关推荐

  1. 图的单源最短路径:Dijkstra算法实现

    本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法 ...

  2. 图的最短路径之Dijkstra求单源最短路径算法(C++)

    一个有向带权图求它的单源最短路径可以使用Dijkstra算法. 单源最短路径是指:从图中的某个顶点出发,到其余各个顶点权值最小的路径. Dijkstra算法需要用到三个辅助数组: dist[max]: ...

  3. 数据结构——最短路径之Dijkstra算法(与最小生成树的prime算法很像,建议一起看)

    最短路径之Dijkstra算法 (一)Dijkstra算法 单源最短路径:就是从某一个顶点出发,到图中任意顶点之间的最短路径: [算法概述]:Dijkstra算法适用于解决单源最短路径的问题.即:从源 ...

  4. dijkstra算法PHP,单源最短路径(dijkstra算法)php实现

    做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi ...

  5. 最短路径之Dijkstra算法

    今天看了最短路径之Dijkstra算法,对这算法,写上自己的心得和感悟! 1.Dijkstra算法,(迪杰斯特拉)--单源最短路径 求的是一个源点到其他顶点的最短路径 算法描述 1).算法思想 设G= ...

  6. 最短路径问题——Dijkstra算法详解(单源最短路径)

    单源最短路径 单源最短路径,是指从图中任一点出发到其他各点之间的最短路径. Dijkstra算法介绍 Dijkstra算法又称迪杰特斯拉算法,dijkstra算法的核心思想是将全部结点所在集合V分成两 ...

  7. 图算法——求最短路径(Dijkstra算法)

    目录 一.什么是最短路径 二.迪杰斯特拉(Dijkstra)算法 三.应用Dijkstra算法 (1) Dijkstra算法函数分析 求图的最短路径在实际生活中有许多应用,比如说在你在一个景区的某个景 ...

  8. 最短路径(Dijkstra算法),一文必看懂最短路径的方法

    最短路径问题(Dijkstra算法) 从图中的某一个顶点出发到达另一个顶点的所经过的边的权重和最小的一条路径,称为最短路径. Dijkstra算法适用于求一个节点到其他节点的最短路径,主要特点是通过广 ...

  9. 数据结构——图——迪杰斯特拉(Dijkstra )算法

    数据结构--图--迪杰斯特拉(Dijkstra )算法 这是一个按路径长度递增的次序产生最短路径的算法.它的思路大体是这样的. 比如说要求图7-7-3中顶点v0到顶点v1的最短距离,没有比这更简单的了 ...

  10. 最短路径的Dijkstra算法(邻接表)

    原文:http://blog.csdn.net/axiqia/article/details/50984464 描述 以邻接表作为存储结构实现,求解从给定源点到给定结束点的最短路径. 输入 从1开始表 ...

最新文章

  1. C# 3.X -- the newest features
  2. windows消息处理机制
  3. Tomcat——访问错误[Invalid character found in method name. HTTP method names must be tokens]解决方案
  4. 2019.9.19最小生成树知识点总结
  5. pandas concat_pandas-数据合并-concat(最全参数解释,含代码和实例)
  6. python分析彩票_[博乐彩票网]福彩3D第2008277期和值和尾分析
  7. oracle 序列开始为2,【图片】【求助】为啥Oracle的sequence 第一次插入表从2开始。。【java吧】_百度贴吧...
  8. LeetCode 229 : Majority Element II
  9. JAVA注解行_java注解
  10. SQL删除重复数据,保留ID最大的一条
  11. 解读HTTP/2与HTTP/3 的新特性(推荐)
  12. CTU CU CB PU TU
  13. php的pdo mysql扩展模块_php pdo链接
  14. Android Edittext设置软键盘输入法Enter回车键为完成按钮
  15. 机电设备如何有效监控?手把手教你最实用的
  16. 远程shell特洛伊木马病毒
  17. 数据结构课程主页-2016级
  18. nanopi neo2 black 上电使用
  19. 【PHM】PHM算法与智能分析技术——智能维护技术引述
  20. 【PYthon报错】np.complex128数字的虚数部分为0j

热门文章

  1. 层次分析法(AHP)原理_例题应用及代码
  2. 如何隐藏SDK中符号
  3. 【Mockplus教程】安装Mockplus
  4. 文件服务器如何设置配额,文件服务器设置配额
  5. 互联网发展的三个阶段
  6. 计算机打不开excel表格,excel表格打不开怎么办?excel表格打不开的原因及解决方法...
  7. 电脑端微信用户图片DAT格式解码为图片
  8. 计算机添加本地安全组用户名和密码错误,win7系统访问远程共享文件夹提示未知的用户名或密码错误的解决方法...
  9. 计算机加硬盘后速度变慢,Win10安装SSD固态硬盘后运行速度还很慢的解决方法
  10. 如何科学进行用户分析?六大方法论了解一下!