设计一个校园导游系统,为来访的客人提供各种信息查询服务。(限1人完成)
(一)基本要求
1、 设计你的学校的校园平面图,所含景点10-15个。以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
2、 为来访客人提供图中任意景点相关信息的查询。
3、 为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。
4、 提供图中任意景点问路查询,即求任意两个景点之间的所有路径。
5、 提供校园图中多个景点的最佳访问路线查询,即求途经这多个景点的最佳路径。
6、 区分汽车线路与步行线路。
7、 设计一实用的查询界面和功能菜单。
(二)、测试数据
由读者根据实际情况设定。
(三)、选做内容
1、 扩充道路信息,如道路类别(车道、人行道等)、沿途景色等级,以至可按客人所需分别查询人行路径和车行路径或观察路径。
2、 扩充每个景点的邻接景点的方向等信息,使得路径查询结果能提供详尽的导向信息。
3、 实现校园导游图的仿真界面。
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX 0x3f3f3f
stack<int> S;
deque <int> dq;
deque <deque<int> > dd;
int mapp[13][13];//步行;
int mapp1[13][13];//驾车
int dis[13]; //最短路
int vis[13]; // 标记
int path[20];
int flag[200]= {0};
int e=0;
int aa[20]= {0};
void dijstra(int b,int a,int c);
void init()//最初将长度存好
{
memset(mapp,MAX,sizeof(mapp));
memset(mapp1,MAX,sizeof(mapp));
memset(dis,MAX,sizeof(dis));
memset(vis,0,sizeof(vis));
mapp[1][2]=mapp[2][1]=200;
mapp[1][4]=mapp[4][1]=50;
mapp[1][5]=mapp[5][1]=80;
mapp[1][7]=mapp[7][1]=90;
mapp[2][3]=mapp[3][2]=40;
mapp[2][4]=mapp[4][2]=130;
mapp[2][6]=mapp[6][2]=50;
mapp[2][8]=mapp[8][2]=40;
mapp[2][9]=mapp[9][2]=55;
mapp[2][10]=mapp[10][2]=170;
mapp[2][11]=mapp[11][2]=280;
mapp[3][4]=mapp[4][3]=230;
mapp[3][8]=mapp[8][3]=5;
mapp[3][9]=mapp[9][3]=35;
mapp[3][10]=mapp[10][3]=28;
mapp[3][12]=mapp[12][3]=380;
mapp[4][5]=mapp[5][4]=50;
mapp[4][7]=mapp[7][4]=55;
mapp[4][10]=mapp[10][4]=180;
mapp[4][12]=mapp[12][4]=300;
mapp[5][6]=mapp[6][5]=80;
mapp[5][7]=mapp[7][5]=15;
mapp[5][10]=mapp[10][5]=200;
mapp[6][7]=mapp[7][6]=65;
mapp[6][8]=mapp[8][6]=275;
mapp[7][10]=mapp[10][7]=220;
mapp[7][11]=mapp[11][7]=440;
mapp[8][9]=mapp[9][8]=55;
mapp[8][10]=mapp[10][8]=35;
mapp[8][11]=mapp[11][8]=235;
mapp[9][10]=mapp[10][9]=89;
mapp[10][11]=mapp[11][10]=215;
mapp[10][12]=mapp[12][10]=181;
mapp[11][12]=mapp[12][11]=175;
mapp1[1][2]=mapp1[2][1]=205;
mapp1[1][4]=mapp1[4][1]=55;
mapp1[1][5]=mapp1[5][1]=85;
mapp1[1][7]=mapp1[7][1]=95;
mapp1[2][3]=mapp1[3][2]=45;
mapp1[2][4]=mapp1[4][2]=135;
mapp1[2][6]=mapp1[6][2]=55;
mapp1[2][8]=mapp1[8][2]=45;
mapp1[2][9]=mapp1[9][2]=60;
mapp1[2][10]=mapp1[10][2]=175;
mapp1[2][11]=mapp1[11][2]=285;
mapp1[3][4]=mapp1[4][3]=235;
mapp1[3][8]=mapp1[8][3]=10;
mapp1[3][9]=mapp1[9][3]=40;
mapp1[3][10]=mapp1[10][3]=30;
mapp1[3][12]=mapp1[12][3]=385;
mapp1[4][5]=mapp1[5][4]=55;
mapp1[4][7]=mapp1[7][4]=65;
mapp1[4][10]=mapp1[10][4]=185;
mapp1[4][12]=mapp1[12][4]=305;
mapp1[5][6]=mapp1[6][5]=85;
mapp1[5][7]=mapp1[7][5]=20;
mapp1[5][10]=mapp1[10][5]=205;
mapp1[6][7]=mapp1[7][6]=70;
mapp1[6][8]=mapp1[8][6]=280;
mapp1[7][10]=mapp1[10][7]=225;
mapp1[7][11]=mapp1[11][7]=445;
mapp1[8][9]=mapp1[9][8]=58;
mapp1[8][10]=mapp1[10][8]=39;
mapp1[8][11]=mapp1[11][8]=243;
mapp1[9][10]=mapp1[10][9]=93;
mapp1[10][11]=mapp1[11][10]=219;
}
void Query()//查询景点编号,信息,简介
{
int a;
cout<<"=========景点编号============"<<endl;
cout<<"= 1. 西校南门 2. 西校人工湖 ="<<endl;
cout<<"= 3. 西苑餐厅 4. 逸夫楼 ="<<endl;
cout<<"= 5. 创业中心 6. 篮球场 ="<<endl;
cout<<"= 7. 图书馆 8. 翕苑超市 ="<<endl;
cout<<"= 9. 专家公寓 10.人工湖 ="<<endl;
cout<<"= 11.实验楼 12.小树林 ="<<endl;
cout<<"============================="<<endl;
cout<<"输入你想查询景点信息的编号(1 ~ 12):";
cin>>a;
if(a==1)
cout<<"* 山东工商学院大门,因面朝南面被称为南门!"<<endl;
else if(a==2)
cout<<"* 操场有400米跑道,足球场,可以进行户外活动!"<<endl;
else if(a==3)
cout<<"* 山东工商学院西校区唯一的餐厅!"<<endl;
else if(a==4)
cout<<"* 山东工商学院西校区的教学楼,外国语学院!"<<endl;
else if(a==5)
cout<<"* 创业孵化基地!"<<endl;
else if(a==6)
cout<<"* 可以打篮球,进行篮球比赛!"<<endl;
else if(a==7)
cout<<"* 图书馆可以借书,上自习,进入需刷校园卡!"<<endl;
else if(a==8)
cout<<"* 山东工商学院西校区超市,可以购买日用品、零食等!"<<endl;
else if(a==9)
cout<<"* 老师、校外专家住宿的地方!"<<endl;
else if(a==10)
cout<<"* 山东工商学院人工湖,景色优美!"<<endl;
else if(a==11)
cout<<"* 新建的实验楼,目前还未完工!"<<endl;
else if(a==12)
cout<<"* 一片树林,景色优美!"<<endl;
else printf("输入不合法!\n");
}
void Query1()//查询两点任意最短路径及长度;
{
int a,b,c;
cout<<"======出行方式====="<<endl;
cout<<"1.步行."<<endl;
cout<<"2.驾车."<<endl;
cout<<"================="<<endl;
cout<<"输入你的选择(1 or 2):";
cin>>a;
cout<<"输入起点编号:";
cin>>b;
cout<<"输入终点编号:";
cin>>c;
if(b<=0&&b>=12||c<=0&&c>=12)
cout<<"输入错误,景点不存在。"<<endl;
else
dijstra(b,a,c);
}
void DIS(int a,int b,int c)//计算dis数组
{
memset(path,0,sizeof(path));
int i,j,pos=1,minn,sum=0;
memset(vis,0,sizeof(vis));
for(i=1; i<=12; i++)
{
if(a==1)
dis[i]=mapp[b][i];
if(a==2)
dis[i]=mapp1[b][i];
}
vis[b]=1;
dis[b]=0;
for(i=1; i<=12; i++)
{
minn=MAX;
for(j=1; j<=12; j++)
{
if(vis[j]==0&&minn>dis[j])
{
minn=dis[j];
pos=j;
}
}
vis[pos]=1;
for(j=1; j<=12; j++)
{
if(a==1)
{
if(vis[j]==0&&dis[j]>dis[pos]+mapp[pos][j])
{
dis[j]=dis[pos]+mapp[pos][j];
path[j]=pos;
}
}
if(a==2)
{
if(vis[j]==0&&dis[j]>dis[pos]+mapp1[pos][j])
{
dis[j]=dis[pos]+mapp1[pos][j];
path[j]=pos;
}
}
}
}
}
void dijstra(int b,int a,int c)//回溯求最短路径
{
DIS(a,b,c);
int x=c;
while(!S.empty())
S.pop();
while(1)
{
if(x==0)
break;
S.push(x);
x=path[x];
}
S.push(b);
if(dis[c]>=100000)
cout<<"没有直达的路,请选择步行。"<<endl;
else
{
cout<<"从"<<b<<"到"<<c<<"的最短路径为:";
while(!S.empty())
{
if(S.size()>1)
cout<<S.top()<<"->";
else
cout<<S.top();
S.pop();
}
cout<<endl<<"其最短距离为:"<<dis[c]<<endl;
}
}
void DFS1(int b,int c)
{
int i,j;
vis[b] = 1;
dq.push_back(b);
for (j = 1; j <=12; j++)
{
if (j==c&&mapp[j][b]<=2000)
{
dd.push_back(dq);
}
if (vis[j]==0&&mapp[b][j]<=2000)
DFS1(j,c);
}
vis[dq.back()] = 0;
dq.pop_back();
}
void DFS2(int b,int c)
{
int i,j;
vis[b] = 1;
dq.push_back(b);
for (j = 1; j <=12; j++)
{
if (j==c&&mapp1[j][b]<=2000)
{
dd.push_back(dq);
}
if (vis[j]==0&&mapp1[b][j]<=2000)
DFS2(j,c);
}
vis[dq.back()] = 0;
dq.pop_back();
}
void Query2()//查询两点所有路径
{
init();
int a,b,c,i,j;
cout<<"======出行方式====="<<endl;
cout<<" 1.步行."<<endl;
cout<<" 2.驾车."<<endl;
cout<<"==================="<<endl;
cout<<"输入你的选择(1 or 2):";
cin>>a;
cout<<"输入起点编号:";
cin>>b;
cout<<"输入终点编号:";
cin>>c;
// 队列 数组清零
while(!dq.empty())
dq.pop_front();
while(!dd.empty())
dd.pop_front();
memset(vis,0,sizeof(vis));
if(a==1)
DFS1(b,c);
else
DFS2(b,c);
if(dd.size()>=3)
{
cout<<"有三条以上(含3条),只输出前三条较短的路径:"<<endl;
int p=0;
for(i=1;; i++)
{
int g=dd.size();
for(j=0; j<g; j++)
{
if(dd.front().size()==i)
{
while(!dd.front().empty())
{
cout<<dd.front().front()<<" ";
dd.front().pop_front();
}
cout<<c<<endl;
p++;
if(p==3)
return;
dd.pop_front();
continue;
}
dd.push_back(dd.front());
dd.pop_front();
}
}
}
else if(dd.size()!=0)
{
while(!dd.empty())
{
while(!dd.front().empty())
{
cout<<dd.front().front()<<" ";
dd.front().pop_front();
}
cout<<c<<endl;
dd.pop_front();
}
}
else
cout<<"没有直接相连的路径!!!"<<endl;
}
void BestPath(int a)//最佳路径
{
int i,j,k,flag1=0;
// 队列 数组清零
while(!dq.empty())
dq.pop_front();
while(!dd.empty())
dd.pop_front();
memset(vis,0,sizeof(vis));
if(a==1)
DFS1(aa[0],aa[e-1]);
else
DFS2(aa[0],aa[e-1]);
int n=dd.size();
int yang=0;
for(k=1;k<=20; k++)
{
for(i=0; i<n; i++)
{
int m=dd.front().size();
int sum=0;
for(j=0; j<m; j++)
{
int hh=dd.front().front();
if(flag[hh]==1)
sum++;
dd.front().pop_front();
dd.front().push_back(hh);
}
if(sum>=e-1&&m==k)
{
flag1=1;
yang++;
if(yang==2)
return ;
cout<<"路径为:";
for(j=0;j<m;j++)
{
cout<<dd.front().front()<<" ";
dd.front().push_back(dd.front().front());
dd.front().pop_front();
}
cout<<aa[e-1]<<" ";
cout<<endl;
}
dd.push_back(dd.front());
dd.pop_front();
}
}if(flag1==0)
cout<<"**不存在这样的路径"<<endl;
}
void Query3()//查询途经多点的最短路径
{
init();
int a;
memset(aa,0,sizeof(aa));
memset(flag,0,sizeof(flag));
cout<<"======出行方式====="<<endl;
cout<<" 1.步行."<<endl;
cout<<" 2.驾车."<<endl;
cout<<"==================="<<endl;
cout<<"输入你的选择(1 or 2):";
cin>>a;
cout<<"输入经过的点(以0结束,默认开始为起始点):";
int b;
while(1)
{
cin>>b;
if(b==0)
break;
else
{
aa[e++]=b;
flag[b]=1;
}
}
aa[e]=0;
BestPath(a);
}
void Plan() //平面图
{
//输出一个平面图
}
void menu() //菜单
{
int a;
init();
while(1)
{
printf("*********欢迎使用山东工商学院导游系统********************\n");
printf("************1.查询景点信息\n");
printf("************2.查询二个景点的最短路径\n");
printf("************3.查询二个景点的所有路径\n");
printf("************4.查询多个景点的最佳路径\n");
printf("************5.查看山东工商学院平面图\n");
printf("************6.退出\n");
printf("请输入你要选择的操作:\n");
scanf("%d",&a);
if(a==0)
break;
if(a==1)
Query();
if(a==2)
Query1();
if(a==3)
Query2();
if(a==4)
Query3();
if(a==5)
Plan();
}
}
int main()
{
menu();
return 0;
}