Dijkstra算法

本文详细介绍了哈工大版的Dijkstra算法无向图实现过程,通过C++代码展示了如何创建图、寻找最短路径及输出结果。Dijkstra算法用于求解单源最短路径问题,代码中特别注意了无向图的特点,即边的双向性。测试样例给出了从不同起点出发到所有顶点的最短路径,帮助理解算法的正确性。
摘要由CSDN通过智能技术生成

哈工大版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

cg
输出结果为:

从定点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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

M_blueberry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值