哈工大版Dijkstra算法无向图实现
Dijkstra算法讲解
哈工大视频讲解:点击此处跳转到b站
测试样例:
5
A B C D E
6
A B 5
A C 6
A D 3
D E 10
E C 15
C B 7
输出结果为:
从定点A出发,到各个顶点的最短距离:
从A到A:0
从A到B:5
从A到C:6
从A到D:3
从A到E:13
从定点B出发,到各个顶点的最短距离:
从B到A:5
从B到B:0
从B到C:7
从B到D:8
从B到E:18
从定点C出发,到各个顶点的最短距离:
从C到A:6
从C到B:7
从C到C:0
从C到D:9
从C到E:15
从定点D出发,到各个顶点的最短距离:
从D到A:3
从D到B:8
从D到C:9
从D到D:0
从D到E:10
从定点E出发,到各个顶点的最短距离:
从E到A:13
从E到B:18
从E到C:15
从E到D:10
从E到E:0
需要解释和注意的问题请看代码注释
C++代码
#include<iostream>
using namespace std;
#include<limits.h> //包含int等类型的最值,若两点不连通则该两点的虚边权值为INT_MAX
struct graph {
char vertlist[100]; //节点名称(如A B C...)
int edgelist[100][100]; //邻接矩阵
int n, e; //n=nodes' count, e=edges' count
};
struct table { //标记当前顶点状态
bool visited; //标记当前顶点是否已被访问
int distance, path; //当前顶点与各个顶点的最小距离(distance)和经过的顶点
};
void CreateGraph(graph*& g) {
g = new graph;
cin >> g->n; //输入顶点个数
for (int i = 1; i <= g->n; i++) {
cin >> g->vertlist[i]; //输入顶点名称(如A B C...)
for (int j = 1; j <= g->n; j++) { //初始化邻接矩阵
if (i != j) g->edgelist[i][j] = INT_MAX;
else g->edgelist[i][j] = 0;
}
}
cin >> g->e; //输入边个数
char temp1, temp2;
int weight, adj1, adj2;
for (int i = 1; i <= g->e; i++) { //将输入的信息转为邻接矩阵储存
cin >> temp1 >> temp2 >> weight;
for (int j = 1; j <= g->n; j++) {
if (g->vertlist[j] == temp1) adj1 = j;
if (g->vertlist[j] == temp2) adj2 = j;
}
g->edgelist[adj1][adj2] = weight;
g->edgelist[adj2][adj1] = weight; //无向图需交换邻接点再次录入边信息
}
}
int Findmin(graph* g,table* t) { //找到距离最进的顶点
int min = INT_MAX, adjmin;
for (int i = 1; i <= g->n; i++)
if (!t[i].visited && t[i].distance < min) {
min = t[i].distance;
adjmin = i;
}
return adjmin;
}
void Dijkstra(graph* g, table* t,int flag) { //从flag顶点出发,求到各个顶点的距离distance(Dijkstra算法)
for (int i = 1; i <= g->n; i++) {
t[i].distance = g->edgelist[flag][i];
t[i].visited = false;
t[i].path = flag;
}
t[flag].visited = true;
int sum, adjmin;
for (int i = 1; i < g->n; i++) { //因为flag顶点已被选出,因此还需选出n-1个顶点
adjmin = Findmin(g, t);
t[adjmin].visited = true;
for (int j = 1; j <= g->n; j++)
if (!t[j].visited&& g->edgelist[adjmin][j]<INT_MAX) { //注:无向图一定要判断 g->edgelist[adjmin][j]<INT_MAX
sum = t[adjmin].distance + g->edgelist[adjmin][j];
if (sum < t[j].distance) {
t[j].distance = sum;
t[j].path = adjmin;
}
}
}
}
int main() {
graph* g;
CreateGraph(g);
table t[100][100];
for (int i = 1; i <= g->n; i++)
Dijkstra(g, t[i], i);//从i顶点出发,求到各个顶点的距离distance,存储在t[i]里
for (int i = 1; i <= g->n; i++) {
cout << "从定点" << g->vertlist[i] << "出发,到各个顶点的最短距离:" << endl;
for (int j = 1; j <= g->n; j++)
cout << "从" << g->vertlist[i] << "到" << g->vertlist[j] <<":"<< t[i][j].distance << endl;
cout << endl;
}
return 0;
}