数据结构(C语言) 实验---图及其应用
[问题描述]
运用Dijkstra算法求最短路径。
1、将导游图看作一张带权无向图,顶点表示公园的各个景点,边表示各景点之间的道路,边上的权值表示距离,选择适当的数据结构。
2、求大门到各个景点之间的一条最短路径。
#include<iostream>
#include<string>
using namespace std;
#define MAX 1000000 //表示极大值∞
#define max 10
bool S[max]; //记录从源点V0到终点Vi是否已经确定为最短路径,确定了记true,否则记false
int Path[max]; //记录从源点V0到终点Vi的当前最短路径上终点Vi的直接前驱顶点序号,若V0到Vi之间有边前驱为V0否则为-1
int D[max]; //记录源点到终点之间最短路径的长度,存在记V0到Vi的边的权值,否则记为MAX
typedef struct
{
string vexs[max]; //顶点表
int arcs[max][max]; //邻接矩阵
int vexnum, arcnum; //图当前点数和边数
}AMGraph;
//利用迪杰斯特拉算法求最短路径
void ShortestPath_DIJ(AMGraph &G, int v0)
{//使用迪杰斯特拉算法求有向网G中的V0 定点到其余顶点的最短路径
int n = G.vexnum;//顶点数
for (int v = 0; v < n; v++)//n个顶点依次初始化
{
S[v] = false;//S初始化为空集
D[v] = G.arcs[v0][v];//将v0到各个终点的最短路径长度初始化为边上的权值
if (D[v] < MAX)
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加到S数组
for (int i = 1; i < n; i++)//依次对其余n-1个顶点进行计算
{
int min = MAX;
int v = v0;
for (int w = 0; w < n; w++)
{
if (!S[w] && D[w] < min)
{//选择一条当前最短路径,终点为v
v = w;
min = D[w];
}
S[v] = true;//将v加到s集合中
for (int 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
}
}
}
}
}
//背景函数
void backGround()
{
cout << "|*****************************************************************|" << endl;
cout << " |---------------------------软院地图--------------------|" << endl;
cout << "|*****************************************************************|" << endl;
cout << "| ⑦ 单位:米 |" << endl;
cout << "| 行政楼 |" << endl;
cout << "| ◎ ⑧ |" << endl;
cout << "| ↗↖ 九,十栋 |" << endl;
cout << "| ③ 200╱ ╲ ◎ |" << endl;
cout << "| 大 ↙ ╲ 150 ↗ ↖ |" << endl;
cout << "| 门 ◎ ╲ ① 160 ╱ ╲ 200 |" << endl;
cout << "| ↖150 ╲ 软件 ⑥ ╱ ╲ |" << endl;
cout << "| ④ ↘ 140 ↘ 楼 200 一食堂 ↙ 230 ↘ |" << endl;
cout << "| 操场 ◎-------------→◎←--------------→◎←---------→◎ |" << endl;
cout << "| ↖ ↗ ↖ ↗ ↖ ↗② |" << endl;
cout << "| 100 ╲ ╱ ╲ 125 ╱ ╲ 150 ╱ 二 |" << endl;
cout << "| ↘ ↙ 100 ╲ ╱135 ╲ ╱145 食 |" << endl;
cout << "| ◎ ↘ ↙ ↘ ↙ 堂 |" << endl;
cout << "| ⑨天龙人学院 ◎ ◎ |" << endl;
cout << "| ⑩ 六栋 ⑤ 遗址 |" << endl;
cout << "| |" << endl;
cout << "|*****************************************************************|" << endl;
}
//主菜单
void menu()
{
cout << "|*****************************************************************|" << endl;
cout << "|----------------------------软院导游小程序-----------------------|" << endl;
cout << " |*********************************************************|" << endl;
cout << " |--------------------1-地点信息查询--------------|" << endl;
cout << " |--------------------2-最短路径查询--------------|" << endl;
cout << " |--------------------3-显示软院视图--------------|" << endl;
cout << " |------------------- 4-退出导游程序------ -------|" << endl;
cout << "|*****************************************************************|" << endl;
cout << ">>>请选择:";
}
//景点信息查询二级菜单
void jmenu()
{
cout << "|*****************************************************************|" << endl;
cout << " |-------------------------地点信息查询------------------------|" << endl;
cout << " |***********************************************************|" << endl;
cout << " |----------------------1-软件楼介绍---------------------| " << endl;
cout << " |----------------------2-二食堂介绍---------------------| " << endl;
cout << " |----------------------3-大门介绍-----------------------| " << endl;
cout << " |----------------------4-操场介绍-----------------------| " << endl;
cout << " |----------------------5-遗址介绍-----------------------| " << endl;
cout << " |----------------------6-一食堂介绍---------------------| " << endl;
cout << " |----------------------7-行政楼介绍---------------------| " << endl;
cout << " |----------------------8-九,十栋介绍--------------------| " << endl;
cout << " |----------------------9-天龙人学院介绍-----------------| " << endl;
cout << " |--------------------- 10-六栋介绍----------------------| " << endl;
cout << "|*****************************************************************|" << endl;
cout << ">>>请要查询的地点编号:";
}
//最短路径查询二级菜单
void pmenu()
{
cout << "|*****************************************************************|" << endl;
cout << " |-------------------------最短路径查询------------------------|" << endl;
cout << " |*******************此处为大门到各点最短路径******************|" << endl;
cout << " |----------------------1-软件楼-----------------------| " << endl;
cout << " |----------------------2-二食堂-----------------------| " << endl;
cout << " |----------------------3-大门-------------------------| " << endl;
cout << " |----------------------4-操场-------------------------| " << endl;
cout << " |----------------------5-遗址-------------------------| " << endl;
cout << " |----------------------6-一食堂-----------------------| " << endl;
cout << " |----------------------7-行政楼-----------------------| " << endl;
cout << " |----------------------8-九,十栋----------------------| " << endl;
cout << " |----------------------9-天龙人学院-------------------| " << endl;
cout << " |--------------------- 10-六栋------------------------| " << endl;
cout << "|*****************************************************************|" << endl;
cout << ">>>请要查询的地点编号:";//
}
int main()
{
//初始化操作
AMGraph amg = { { "软件楼","二食堂","大门","操场","遗址",
"一食堂", "行政楼", "九,十栋", "天龙人学院", "六栋" },
//-1代表两边不相连,权值无限大
//邻接矩阵 /* 软 二 门 场 遗 一 政 九 天 六*/
{{MAX,MAX,MAX,140,MAX,200,150,MAX,100,125 },
{MAX,MAX,MAX,MAX,145,230,MAX,100,MAX,MAX },
{MAX,MAX,MAX,150,MAX,MAX,200,MAX,MAX,MAX },
{140,MAX,150,MAX,MAX,MAX,MAX,MAX,100,MAX },
{MAX,145,MAX,MAX,MAX,150,MAX,MAX,MAX,MAX },
{200,230,MAX,MAX,150,MAX,MAX,160,MAX,135 },
{150,MAX,200,MAX,MAX,MAX,MAX,MAX,MAX,MAX },
{MAX,200,MAX,MAX,MAX,160,MAX,MAX,MAX,MAX },
{100,MAX,MAX,100,MAX,MAX,MAX,MAX,MAX,MAX },
{125,MAX,MAX,MAX,MAX,135,MAX,MAX,MAX,MAX }
},10,14};
int f, ff;
int start, end;
while (true)
{
cout << endl;
menu();
cin >> f;
if (f == 1)
{
jmenu();
cin>>ff;
cout << "|-----------------------地点介绍-------------------| " << endl;
if (ff == 1)
cout << "暂无" << endl;
else if (ff == 2)
cout <<" 暂无" << endl;
else if (ff == 3)
cout <<" 暂无" << endl;
else if(ff == 4)
cout <<" 暂无" << endl;
else if (ff == 5)
cout <<" 暂无" << endl;
else if (ff == 6)
cout <<" 暂无" << endl;
else if (ff == 7)
cout <<" 暂无" << endl;
else if (ff == 8)
cout <<" 暂无" << endl;
else if (ff == 9)
cout <<" 暂无" << endl;
else if (ff == 10)
cout <<" 暂无" << endl;
cout << "|-------------------------------------------------|" << endl;
}
else if (f == 2)
{
pmenu();
cin >> end;
ShortestPath_DIJ(amg, 3 - 1);
int temp = end-1;
int temp1, temp2;
int flag[max], m = 0;
cout << "从" << amg.vexs[3 - 1] << "到" << amg.vexs[end - 1] << "最短路径为:" ;
while (temp!= -1)
{
flag[m++] = temp;
temp1 = temp ;
temp2 = Path[temp1];
temp = temp2;
}
for (int i = m-1; i >= 0; i--)
{
cout <<amg.vexs[flag[i]] << "->";
}
cout << endl;
cout << "最短路径值为:" << D[end - 1] <<"米"<< endl;
}
else if (f == 3)
{
backGround();
}
else if (f == 4)
{
cout << ">>>退出成功!" << endl;
exit(0);
}
}
}
实验结果