根据题目内容,需要用无向网表示所在学校的景点平面图,即校内每个景点
为无向网中的各个结点,景点的编号、名称、简介等信息存储在结点中,图中的 边表示景点间的道路,存放景点之间的路径长度等信息。需要回答有关景点介绍、
游览路径等问题。具体要求为:
(1) 能够查询各个景点的相关信息。
(2) 查询图中任意两个景点间的最短路径。
(3) 查询图中任意两个景点间的所有路径。
(4) 增加、删除、更新有关景点和道路的信息。
选取10个代表性景点
实现代码
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
#include<string.h>
#include<algorithm>
#include<stack>
#define INF 9999999
#define MAX 30
int dist[MAX][MAX];///距离
int path[MAX][MAX];///路径
int Stack[MAX];///路径栈
int top;///栈顶
int counts;///记录路径数
typedef struct VexNode//景点信息结构体
{
int vertex;//景点编号
char name[20];//景点名称
char vertax_message[400];//景点介绍
}VerNode;
typedef struct maps//景点图的结构体
{
VerNode v[MAX];
int vexnum;//点数
int arcnum;//边数
int edgs[MAX][MAX];//邻接矩阵
}AdjList;
int visited[MAX];
void create_vertex(AdjList &GL);//初始化校园景点及景点信息函数
void Init_Creat_maps(AdjList & GL);//初始化校园景点图函数
void Dis_menu();//展示程序菜单
void Dis_map();//展示校园景点图
void add_message(AdjList &GL);//更新或添加或删除校园景点及路径信息函数
void find_message(AdjList GL);//查询景点信息函数
void Floyd(AdjList GL);//弗洛伊德求最短路径
void Floyd_print(int s, int e,AdjList GL);//打印最短路径
void Dfs_allpaths(int s,int e,AdjList GL);//查询两景点之间所有路径函数
void message(AdjList GL);//已有景点
int main()
{ AdjList graph;
int key;
int start,end;
create_vertex(graph);
Init_Creat_maps(graph);
while(1)
{
Dis_menu();
cin>>key;
if(key==1)
{
Dis_map();
find_message(graph);
system("pause");
system("cls");
}
if(key==2)
{
message(graph);
printf("请输入起点的景点(编号):\n");
scanf("%d",&start);
printf("请输入起点的终点(编号):\n");
scanf("%d",&end);
Floyd(graph);
printf("从%s到%s的最短路径是:%d米 ",graph.v[start].name,graph.v[end].name,dist[start][end]);
printf("%s->",graph.v[start].name);
Floyd_print(start,end,graph);
printf("%s\n",graph.v[end].name);
system("pause");
system("cls");
}
if(key==3)
{
message(graph);
printf("请输入起点的景点(编号):\n");
scanf("%d",&start);
printf("请输入起点的终点(编号):\n");
scanf("%d",&end);
counts=0;
top=0;
Dfs_allpaths(start,end,graph);
system("pause");
system("cls");
}
if(key==4)
{
message(graph);
add_message(graph);
system("pause");
system("cls");
}
if(key==0)
{
printf("使用结束!\n");
printf("即将退出安工程校园导游系统.....");
break;
}
if(key>4||key<0)
{
printf("输入有误!请重新输入!");
continue;
}
}
return 0;
}
void create_vertex(AdjList &GL)
{
//预置初始时景点图的景点信息
GL.v[1].vertex=1;
strcpy(GL.v[1].name,"网球场");
strcpy(GL.v[1].vertax_message,"网球场是安工程校园的一个户外运动场地,提供给师生们进行网球运动的场所。这里有专业的网球场地和设施,可以让你尽情享受网球运动的乐趣。");
GL.v[2].vertex=2;
strcpy(GL.v[2].name,"体育馆");
strcpy(GL.v[2].vertax_message,"体育馆是安工程校园内的一个综合性体育场馆,设有多个室内运动场地,如篮球场、羽毛球场、乒乓球场等。师生们可以在这里进行各种体育锻炼和比赛活动。");
GL.v[3].vertex=3;
strcpy(GL.v[3].name,"英语角");
strcpy(GL.v[3].vertax_message,"英语角是安工程校园内一个特殊的交流区域,提供给学生们练习英语口语和交流的场所。在这里,你可以与其他同学自由对话,提高自己的英语口语能力。");
GL.v[4].vertex=4;
strcpy(GL.v[4].name,"情人桥");
strcpy(GL.v[4].vertax_message,"情人桥是安工程校园内的一座浪漫的小桥,因其景色优美而得名。这里是情侣们约会和散步的热门地点,也是学生们放松心情的好去处。");
GL.v[5].vertex=5;
strcpy(GL.v[5].name,"师生活动中心");
strcpy(GL.v[5].vertax_message,"师生活动中心是安工程校园的一个集休闲、娱乐、学习于一体的场所。这里有图书馆、电影院、多功能厅等设施,为师生们提供了丰富多样的活动和学习资源。\n学生处、招生就业处、校团委、校史馆、校学生会联合会、校社团联合会、校大学生艺术团在此办公。");
GL.v[6].vertex=6;
strcpy(GL.v[6].name,"建设银行");
strcpy(GL.v[6].vertax_message,"建设银行是安工程校园内的一家银行分支机构,为师生们提供金融服务,包括存取款、贷款、理财等。方便师生们进行日常的金融交易和管理。");
GL.v[7].vertex=7;
strcpy(GL.v[7].name,"图书馆");
strcpy(GL.v[7].vertax_message,"图书馆是安工程校园内的知识殿堂,收藏了大量的图书、期刊和电子资源,供师生们进行学习和研究使用。这里安静舒适,是学习的理想场所。");
GL.v[8].vertex=8;
strcpy(GL.v[8].name,"校医院");
strcpy(GL.v[8].vertax_message,"校医院是安工程校园内的医疗机构,为师生们提供基本的医疗服务和健康咨询。在这里,你可以得到医生的诊断和治疗,保障自己的健康。");
GL.v[9].vertex=9;
strcpy(GL.v[9].name,"行政楼");
strcpy(GL.v[9].vertax_message,"行政楼是安工程校园的行政管理中心,是学校各项决策和管理工作的重要场所。这里有学校领导和行政人员办公,处理学校相关的事务。");
GL.v[10].vertex=10;
strcpy(GL.v[10].name,"国家广告产业园");
strcpy(GL.v[10].vertax_message,"国家广告产业园是安工程校园内的一个特殊园区,致力于培育和发展广告产业。这里有一些广告公司和机构设立,为师生们提供实习和就业机会。该园区也举办各类广告相关的活动和展览。");
}
void Init_Creat_maps(AdjList & GL)
{
//初始景点图
int i,j;
GL.vexnum=10;///10个景点
GL.arcnum=8;///8条双向路径
for(i=1; i<=MAX; i++) ///初始化邻接矩阵
{
for(j=1; j<=MAX; j++)
{
GL.edgs[i][j]=INF;
}
}
GL.edgs[1][3]=GL.edgs[3][1]=410;
GL.edgs[1][4]=GL.edgs[4][1]=300;
GL.edgs[2][7]=GL.edgs[7][2]=400;
GL.edgs[2][4]=GL.edgs[4][2]=420;
GL.edgs[3][4]=GL.edgs[4][3]=180;
GL.edgs[4][5]=GL.edgs[5][4]=280;
GL.edgs[1][7]=GL.edgs[7][1]=430;
GL.edgs[1][2]=GL.edgs[2][1]=340;
}
void Dis_menu()
{
printf("\n\n");
printf("\t\t\t****************安工程校园导游系统*********************\n");
printf("\t\t\t* 作者:魏永雷 班级:数据科学221 学号:3220706134 *\n");
printf("\t\t\t* *\n");
printf("\t\t\t* <1>. 安工程景点信息查询 *\n");
printf("\t\t\t* <2>. 两景点之间最短路查询 *\n");
printf("\t\t\t* <3>. 两景点间所有路径查询 *\n");
printf("\t\t\t* <4>. 景点和路径信息的删除或增加(更新) *\n");
printf("\t\t\t* <0>. 退出系统 *\n");
printf("\t\t\t* 欢迎使用本系统! *\n");
printf("\t\t\t*******************************************************\n");
printf("\t\t\t输入选项,按回车进入选项: \n");
return ;
}
void Dis_map()
{
printf("\n ******安工程校园景点地图一览******\n\n");
printf(" ----------◎ ⑤师生活动中心 \n");
printf(" | | \n");
printf(" | | \n");
printf(" ①网球场 ②体育馆 | \n");
printf(" ◎ ◎--------------------| \n");
printf(" |-----------| | \n");
printf(" | | | \n");
printf(" ③英语角◎-------- ④情人桥◎ |\n");
printf(" ⑧校医院◎------------|--------------------|--------------------| \n");
printf(" | | ◎--------| \n");
printf(" | | 校园湖 | \n");
printf(" | ◎⑨行政楼 | \n");
printf(" ◎⑦图书馆 | | \n");
printf(" |-------------------------------| | \n");
printf(" | |-------------- ◎⑩国家广告产业园 \n");
printf(" | \n");
printf(" ◎⑥建设银行 | \n\n");
}
void add_message(AdjList &GL)
{
int num,p,q,num1,num2,p1,q1;
VerNode *t;
t=GL.v;
while(1)
{
num=-1;
printf("********************************************************************************************\n");
printf("输入‘1’增加(更新)景点信息,输入‘2’增加(更新)路径信息,输入‘3’删除景点信息,输入‘4’删除路径信息:\n");
printf("输入‘0’则退出\n");
printf("********************************************************************************************\n");
cin>>num;
if(num==0)
{
break;
}
if(num==1)
{
printf("请依次输入要增加信息的景点的编号,景点名称,景点介绍:\n");
printf("注意:如果景点为新增的景点编号需要在原来基础上递增!\n");
scanf("%d",&num1);
if(num1>GL.vexnum)
{
GL.vexnum+=1;
}
GL.v[num1].vertex=num1;
cin>>GL.v[num1].name;
cin>>GL.v[num1].vertax_message;
continue;
}
if(num==2)
{
GL.arcnum+=1;
printf("请输入增加路径的详细信息及其长度(用景点编号表示):\n");
cout<<"例如:1 2 "<<endl;
cout<<" 200 "<<endl;
scanf("%d %d",&p,&q);
cin>>GL.edgs[p][q];//输入长度
GL.edgs[q][p]=GL.edgs[p][q];//路径为双向路径
continue;
}
if(num==3)
{
printf("请输入要删除信息的景点的编号:\n");
scanf("%d",&num2);
strcpy(GL.v[num2].name,"0");//置0代表删除
strcpy(GL.v[num2].vertax_message,"0");//置0代表删除
continue;
}
if(num==4)
{
printf("请输入删除的路径(用景点编号表示):\n");
scanf("%d %d",&p1,&q1);
GL.edgs[p1][q1]=INF;
GL.edgs[q1][p1]=INF;
continue;
}
}
}
void message(AdjList GL)
{
printf("景点图已有景点如下:\n");
for(int i=1;i<=GL.vexnum;i++)
{
printf("%d:%s\n",GL.v[i].vertex,GL.v[i].name);
}
}
void find_message(AdjList GL)
{
int number;
printf("景点图已有景点如下:\n");
for(int i=1;i<=GL.vexnum;i++)
{
printf("%d:%s\n",GL.v[i].vertex,GL.v[i].name);
}
while(1)
{
printf("请输入要查询的景点的编号:\n");
printf("输入0则退出\n\n");
cin>>number;
if(number==0)
{
break;
}
else if(number>GL.vexnum||number<0)
{
printf("输入有误,请重新输入:\n");
continue;
}
else
{
printf("%d: %s\n",GL.v[number].vertex,GL.v[number].name);
printf("%s\n",GL.v[number].vertax_message);
}
}
}
void Floyd(AdjList GL) //弗洛伊德
{
int i,j,k;
for(i=1; i<=GL.vexnum; i++) //初始化距离与路径矩阵
{
for(j=1; j<=GL.vexnum; j++)
{
dist[i][j]=GL.edgs[i][j];
if(i!=j&&dist[i][j]<INF)
{
path[i][j]=i;
}
else
{
path[i][j]=-1;//-1代表不可达
}
}
}
//printf("%d\n",GL.);
for(k=1; k<=GL.vexnum; k++)
{
for(i=1; i<=GL.vexnum; i++)
{
for(j=1; j<=GL.vexnum; j++)
{
if(dist[i][j]>(dist[i][k]+dist[k][j]))
{
dist[i][j]=dist[i][k]+dist[k][j];//更新
path[i][j]=k; //path用于记录最短路径上的结点
}
}
}
}
return ;
}
void Floyd_print(int s, int e,AdjList GL)
{
if(path[s][e]==-1||path[s][e]==e||path[s][e]==s)//递归终止条件
{
return;
}
else
{
Floyd_print(s,path[s][e],GL);//将中间点作为终点继续打印路径
printf("%s->",GL.v[path[s][e]].name);//打印中间景点名字
Floyd_print(path[s][e],e,GL);//将中间点作为起点继续打印路径
}
}
void Dfs_allpaths(int s,int e,AdjList GL)
{
int dis=0;
int i,j;
Stack[top]=s;
top++; //起点入栈
visited[s]=1;//标记入栈
for(i=1; i<=GL.vexnum; i++)
{
if(GL.edgs[s][i]>0 && GL.edgs[s][i]!=INF && !visited[i])
{
//表明两点可达且未被访问
if(i==e)//DFS到了终点,打印路径
{
printf("第%d条路:",++counts);
for(j=0; j<top; j++)
{
printf("%s->",GL.v[Stack[j]].name);
if(j<top-1)//统计路径长度
{
dis=dis+GL.edgs[Stack[j]][Stack[j+1]];
}
}
dis=dis+GL.edgs[Stack[top-1]][e];
printf("%s\n",GL.v[e].name);//打印终点
printf("总长度是:%dm\n\n",dis);
}
else//不是终点接着DFS
{
Dfs_allpaths(i,e,GL);
top--;//支路全被访问一遍,顶点出栈
visited[i]=0;//出栈点标记为已出栈,允许下次访问
}
}
}
}
调试结果
5.2 测试样例与结果
5.2.1 初始化景点信息
(1)初始化预制校园景点图:
图 5-1 预制校园景点图
(2)可查询景点一览:
图 5-2 可查询景点一览
5.2.2 景点信息查询功能
(1)查询景点信息测试样例1:
图 5-3 景点信息查询功能测试结果1
(2)查询景点信息测试样例2:
图 5-4 景点信息查询功能测试结果2
(3)查询景点信息测试样例3:
图 5-5 景点信息查询功能测试结果3
5.2.3 两景点最短路径查询功能
(1)查询两景点最短路径测试样例1:
图 5-6 两景点最短路径查询功能测试结果1
(2)查询两景点最短路径测试样例2:
图 5-7 两景点最短路径查询功能测试结果2
(3)查询两景点最短路径测试样例3:
图 5-8 两景点最短路径查询功能测试结果3
5.2.4 两景点所有路径查询功能
(1)查询两景点所有路径测试样例1:
图 5-9 两景点所有路径查询功能测试结果1
(2)查询两景点所有路径测试样例2:
图 5-10 两景点所有路径查询功能测试结果2
(3)查询两景点所有路径测试样例3:
图 5-11 两景点所有路径查询功能测试结果3
5.2.5 增加更新或删除景点信息功能
(1)增加更新景点信息测试样例1:
图 5-12 增加更新景点信息功能测试样例1
图 5-13 增加更新景点信息功能样例1测试结果1
图 5-14 增加更新景点信息功能样例1测试结果2
(2)增加更新景点信息测试样例2:
图 5-15 增加更新景点信息功能测试样例2
图 5-16 增加更新景点信息功能样例2测试结果1
图 5-17 增加更新景点信息功能样例2测试结果2
(3)增加更新景点信息测试样例3:
图 5-18 增加更新景点信息功能测试样例3
图 5-19 增加更新景点信息功能样例3测试结果1
图 5-20 增加更新景点信息功能样例3测试结果2
(4)删除景点信息功能测试样例1:
图 5-21 删除景点信息功能测试样例1
图 5-22 删除景点信息功能测试样例1测试结果1
注意:其中删除的景点全部信息置为0,不然程序会出错误。(下同)
图 5-23 删除景点信息功能测试样例1测试结果2
注意:为避免程序出错,最短路径9999999米是设定的宏定义无穷大,即为没有这条路的意思。(下同)
(5)删除景点信息功能测试样例2:
图 5-24 删除景点信息功能测试样例2
图 5-25 删除景点信息功能测试样例2测试结果1
图 5-26 删除景点信息功能测试样例2测试结果2
(6)删除景点信息功能测试样例3:
图 5-27 删除景点信息功能测试样例3
图 5-28 删除景点信息功能测试样例3测试结果1
图 5-29 删除景点信息功能测试样例3最短路径原结果
图 5-30 删除景点信息功能测试样例3测试结果