【数据结构/C语言版】【图】单源最短路径 Dijkstra
Dijkstra 迪杰斯特拉算法迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法(单源最短路)。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。朴素Dijkstra时间复杂度o(n^2)。优先队列优化Dijkstra时间复
·
Dijkstra 迪杰斯特拉算法
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法(单源最短路)。
迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
朴素Dijkstra时间复杂度o(n^2)。
优先队列优化Dijkstra时间复杂度为 o(m log n)。
测试数据
1
6 8
1 2 3 4 5 6
1 3 10
1 5 30
1 6 100
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60
测试输出
0
1061109567
10
50
30
60
Dijkstra代码
typedef bool PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
bool final[MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];
void ShortestPath_DIJ(MGraph G, int v0, PathMatrix& P, ShortPathTable& D)
{
//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径p[v]及带权长度D[v]
//若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点
//final[v]为TRUE当且仅当v属于s,即已求得从v0到v的最短路径
int v, min;
for (v = 0; v < G.vexnum; v++) {
final[v] = false; D[v] = G.arcs[v0][v].adj;
for (int w = 0; w < G.vexnum; w++) P[v][w] = false;//设空路径
if (D[v] < INFINITY) { P[v][v0] = true; P[v][v] = true; }
}
//初始化v0属于s集
D[v0] = 0; final[v0] = true;
for (int i = 1; i < G.vexnum; i++) {//其余G.vexnum - 1个顶点
min = INFINITY;//当前所知离v0点最近距离
for (int w = 0; w < G.vexnum; w++) {
if(!final[w])
if (D[w] < min) { v = w; min = D[w]; }
}
final[v] = true;
for (int w = 0; w < G.vexnum; w++) {
if (!final[w] && (min + G.arcs[v][w].adj < D[w])) {
D[w] = min + G.arcs[v][w].adj;
for (int i = 0; i < G.vexnum; i++) P[w][i] = P[v][i];
P[w][w] = true;//P[w] = P[v] + [w]
}
}
}
}
完整代码
#include<iostream>
#include<climits>
#include<string>
#include<cstdlib>
using namespace std;
#define ERROR -1
#define MAX_VERTEX_NUM 20 //最多顶点个数
#define INFINITY 0x3f3f3f3f //最大值
typedef enum { DG, DN, UDG, UDN } GraphKind; //有向图、有向网、无向图、无向网
typedef int VRType, Status;
typedef string VertexType;
typedef struct ArcCell {
VRType adj; //VRType是顶点关系类型。对无权图用0
//表示相邻否;对带权图则为权值类型
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum, arcnum; //图的当前顶点数和弧数
int kind;
}MGraph;
//根据映射定位下标
int LocateVex(MGraph G, VertexType v)
{
for (int i = 0; i < G.vexnum; i++) {
if (v == G.vexs[i]) return i;
}
return ERROR;
}
Status CreateDG(MGraph& G)//有向图
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
G.arcs[i][j].adj = 1;
}
return 1;
}
Status CreateDN(MGraph& G)//有向网
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
cout << "请输入包含的额外信息(边权):\n";
cin >> G.arcs[i][j].adj;
}
return 1;
}
Status CreateUDG(MGraph& G)//无向图
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
G.arcs[i][j].adj = G.arcs[j][i].adj = 1;
}
return 1;
}
Status CreateUDN(MGraph& G)//无向网
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入第" << i + 1 << "向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
int w; // 权重
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
cout << "请输入包含的额外信息(边权):\n";
cin >> G.arcs[i][j].adj;
G.arcs[j][i].adj = G.arcs[i][j].adj;
}
return 1;
}
Status CreateGraph(MGraph& G)
{
cin >> G.kind;
switch (G.kind)
{
case DG:return CreateDG(G);
case DN:return CreateDN(G);
case UDG:return CreateUDG(G);
case UDN:return CreateUDN(G);
default: return ERROR;
}
}//CreateGraph
void TraveGraph(MGraph G)
{
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
cout << G.arcs[i][j].adj << ' ';
}
cout << '\n';
}
}
typedef bool PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
bool final[MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];
void ShortestPath_DIJ(MGraph G, int v0, PathMatrix& P, ShortPathTable& D)
{
//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径p[v]及带权长度D[v]
//若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点
//final[v]为TRUE当且仅当v属于s,即已求得从v0到v的最短路径
int v, min;
for (v = 0; v < G.vexnum; v++) {
final[v] = false; D[v] = G.arcs[v0][v].adj;
for (int w = 0; w < G.vexnum; w++) P[v][w] = false;//设空路径
if (D[v] < INFINITY) { P[v][v0] = true; P[v][v] = true; }
}
//初始化v0属于s集
D[v0] = 0; final[v0] = true;
for (int i = 1; i < G.vexnum; i++) {//其余G.vexnum - 1个顶点
min = INFINITY;//当前所知离v0点最近距离
for (int w = 0; w < G.vexnum; w++) {
if(!final[w])
if (D[w] < min) { v = w; min = D[w]; }
}
final[v] = true;
for (int w = 0; w < G.vexnum; w++) {
if (!final[w] && (min + G.arcs[v][w].adj < D[w])) {
D[w] = min + G.arcs[v][w].adj;
for (int i = 0; i < G.vexnum; i++) P[w][i] = P[v][i];
P[w][w] = true;//P[w] = P[v] + [w]
}
}
}
}
int main()
{
MGraph G;
cout << "请输入要创建的图的类型(有向图 0、有向网 1、无向图 2、无向网 3):\n";
CreateGraph(G);
//TraveGraph(G);
PathMatrix P;
ShortPathTable D;
ShortestPath_DIJ(G, 0, P, D);
for (int i = 0; i < G.vexnum; i++) {
cout << D[i] << endl;
}
return 0;
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)