这个算法是一种单源最短路径算法,即这个算法只能求出一个点到其他点之间的最短路径,而且这个算法不能处理负边权的图。
算法思路:我们先初始化存图的邻接矩阵,如果我们要求S点到T点的最短距离,我们先初始dis[T](dis[T]表示S点到T点的距离),我们还可以借助一个辅助数组col[]来对这个dis[]进行标记,当col[T]为1时,说明S点到T点的最短距离已经找到。这里我们借助枚举量来对辅助数组进行初始化。
enum Color{Blue,White};//Blue表示是蓝点,需要我们进行检测,White表示不用检测
然后对dis[]数组进行初始化,先将该数组的所有值变为正无穷(dis[S]=0->自己到自己的距离,并将这个下标为S的点染色成白色),表示两点不可达,然后与邻接矩阵配合使用,然后在dis[]数组里找一个下标V使得dis[V]为最小,V标记为白色,在邻接矩阵中查看与V相连的点与V的距离,如果dis[T]>dis[V]+graph[V][T],这个表达式表达S点到T的距离大于S点到V点的距离加上V点到T点的距离,那么将更新dis[]数组为dis[T]=dis[V]+graph[V][T]。然后再进行循环,继续检测dis[]数组里未染成白色的点。
算法步骤:
1.dis[S]=0,col[S]=Color::Blue;
2.dis[!S]=+∞(初始化下标不为S的点为正无穷)
3.for(int i=1;i<=N;i++){//N为点的个数
if(dis[T]>dis[V]+graph[V][T])dis[T]=dis[V]+graph[V][T];
}
4.算法结束,dis[T]表示从S点T点的最短距离
Dijktrea.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
enum Color{Blue,White};
void Dijkstra(int dis[], int col[], int** graph,int s,int len) {//s为源点,len点的个数
dis[s] = 0;//源点到源点的距离为0,
while (true) {
int minV = -1;//标记最短距离的下标
int max = 0x3f3f3f3f;
for (int i = 0; i < len; i++) {
if (col[i] == Color::Blue && dis[i] < max) {//从蓝色点的中找最小值
minV = i;
max = dis[i];
}
}
if (minV == -1)break;//说明所有的点都已经找到最短路径
col[minV] = Color::White;//标记说明这个点已经找到最小值
for (int i = 0; i < len; i++) {
if (dis[i] > dis[minV] + graph[minV][i]) {
dis[i] = dis[minV] + graph[minV][i];
}
}
}
}
int main() {
int V_num;
cout << "please input V number:";
cin >> V_num;
int** graph = new int*[V_num];//动态定义二维数组,先申请int*类型的一维指针
for (int i = 0; i < V_num; i++) {
graph[i] = new int[V_num];//再给申请的一维指针分配int类型空间
}
//邻接矩阵的初始化
for (int i = 0; i < V_num; i++) {
for (int j = 0; j < V_num; j++) {
if (i == j) {
graph[i][j] = 0;
}
else {
graph[i][j] = 0x3f3f3f3f;//表示两点之间不可达
graph[j][i] = graph[i][j];说明是无向图
}
}
}
cout << "graph init success!!!" << endl;
int E_num;
cout << "please input E number:";
cin >> E_num;
cout << "please input E1andE2 and E1toE2_num:" << endl;;//点与点之间的连接关系
for (int i= 0; i < E_num; i++) {
int E1, E2, E1toE2_num;
cin >> E1 >> E2 >> E1toE2_num;
E1 -= 1;
E2 -= 1;
graph[E1][E2] = E1toE2_num;//邻接矩阵存放点与点之间的联通关系与距离
graph[E2][E1] = E1toE2_num;
}
int* dis =new int[V_num];
for (int i = 0; i < V_num; i++) {//源点到目标点数组的初始化
dis[i] = 0x3f3f3f3f;
}
int* col = new int[V_num];
for (int i = 0; i < V_num; i++) {
col[i] = Color::Blue;//初始化辅助数组,蓝点表示最短路径未求出
}
int s, t;
cout << "please input S and T:";
cin >> s >> t;
Dijkstra(dis, col, graph, s - 1, V_num);
cout << "S to T min distance:";
cout << dis[t - 1] << endl;
return 0;
}
/*
测试样例
3->三个点
3->点与点之间的连通关系和距离
1 2 5
2 3 5
3 1 2
1 2->第一个点到第二个点的距离
*/
时间复杂度:O(N^2)