1、实验内容:
利用狄克斯特拉(Dijkstra)算法求上图中0结点到其它结点的最短路径,算法实现代码必须有注释。
2、实现代码:
#include<iostream>
using namespace std;
#define MVNum 100 //最大顶点数
#define MaxInt 32767 //表示极大值,即∞
//利用狄克斯特拉(Dijkstra)算法求上图中0结点到其它结点的最短路径,算法实现代码必须有注释。
int *D = new int[MVNum]; //用于记录最短路的长度
bool *S = new bool[MVNum]; //标记顶点是否进入S集合
int *Path = new int[MVNum]; //用于记录最短路顶点的前驱int *D=new int[MVNum]; //用于记录最短路的长度
//图的邻接矩阵
typedef struct
{
char vexs[MVNum]; //顶点表
int arcs[MVNum][MVNum]; //邻接矩阵
}Graph;
void InitGraph(Graph &G, int vex)
{
cout << "输入点的名称,如a" << endl;
for (int i = 0; i < vex; ++i) {
cout << "请输入第" << (i + 1) << "个点的名称:";
cin >> G.vexs[i]; //依次输入点的信息
}
cout << endl;
for (int i = 0; i < vex; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
for (int j = 0; j < vex; ++j)
{
if (j != i)
G.arcs[i][j] = MaxInt;
else
G.arcs[i][j] = 0;
}
}
//确定点v在G中的位置
int LocateVex(Graph G, char v, int vex) {
for (int i = 0; i < vex; ++i)
if (G.vexs[i] == v)
return i;
return -1;
}
//采用邻接矩阵表示法,创建无向网G
void CreateUDN(Graph &G, int vex, int arc)
{
int i, j, k;
cout << "输入边依附的顶点,如a b 和边对应的权值(用空格隔开)" << endl;
for (k = 0; k < arc; ++k) { //构造邻接矩阵
char v1, v2;
int o;
cout << "请输入第" << (k + 1) << "条边依附的顶点和对应的权值:";
cin >> v1 >> v2 >> o; //输入一条边依附的顶点及权值
i = LocateVex(G, v1, vex); j = LocateVex(G, v2, vex); //确定v1和v2在G中的位置,即顶点数组的下标
G.arcs[j][i] = G.arcs[i][j] = o; //置<v1, v2>的对称边<v2, v1>的权值为w
}
}
void DisplayGraph(Graph G, int vex)
{
int i, j;
for (i = 0; i < vex; ++i) {
for (j = 0; j < vex; ++j) {
if (G.arcs[i][j] != MaxInt)
cout << G.arcs[i][j] << "\t";
else
cout << "∞" << "\t";
}
cout << endl;
}
}
//用Dijkstra算法求无向网G的v0顶点到其余顶点的最短路径
void ShortestPath_DIJ(Graph G, int v0,int vex) {
int v, i, w, min;
int n = vex; //n为G中顶点的个数
for (v = 0; v < n; ++v) { //n个顶点依次初始化
S[v] = false; //S初始为空集
D[v] = G.arcs[v0][v]; //将v0到各个终点的最短路径长度初始化为弧上的权值
if (D[v] < MaxInt) Path[v] = v0; //如果v0和v之间有弧,则将v的前驱置为v0
else Path[v] = -1; //如果v0和v之间无弧,则将v的前驱置为-1
}
S[v0] = true; //将v0加入S
D[v0] = 0; //源点到源点的距离为0
/*―初始化结束,开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
for (i = 1; i < n; ++i) { //对其余n-1个顶点,依次进行计算
min = MaxInt;
for (w = 0; w < n; ++w)
if (!S[w] && D[w] < min) { //选择一条当前的最短路径,终点为v
v = w;
min = D[w];
}//if
S[v] = true; //将v加入S
for (w = 0; w < n; ++w) //更新从v0出发到集合V?S上所有顶点的最短路径长度
if (!S[w] && (D[v] + G.arcs[v][w] < D[w])) {
D[w] = D[v] + G.arcs[v][w]; //更新D[w]
Path[w] = v; //更改w的前驱为v
}
}
for (int i = 0; i <vex; i++) {
if (D[i] != 0)
if (D[i] != MaxInt)
cout << "到" << G.vexs[i] << "最短路径长度:" << D[i] << endl;
else
{
cout << "到" << G.vexs[i] << "最短路径长度:" << "无法到达" << endl;
}
}
}
int main()
{
Graph G;
int vexnum, arcnum; //图的当前点数和边数
cout << "请输入总顶点数,总边数,以空格隔开:";
cin >> vexnum >> arcnum; //输入总顶点数,总边数
cout << endl;
InitGraph(G, vexnum);
int v = 0;
CreateUDN(G, vexnum, arcnum);
cout << endl;
cout << "无向图G创建完成!" << endl << endl;
DisplayGraph(G, vexnum);
int v0 = LocateVex(G, '0', vexnum);
ShortestPath_DIJ(G, v0, vexnum);
}
3、实验结果: