(一)基本要求
1、设计学校的校园平面图,所含景点10-15个。以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
2、为来访客人提供图中任意景点相关信息的查询。
3、为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。
4、提供图中任意景点问路查询,即求任意两个景点之间的所有路径。
5、提供校园图中多个景点的最佳访问路线查询,即求途经这多个景点的最佳路径。
6、区分汽车线路与步行线路。
7、设计一实用的查询界面和功能菜单。
(二)、选做内容
1、扩充道路信息,如道路类别(车道、人行道等)、沿途景色等级,以至可按客人所需分别查询人行路径和车行路径或观察路径。
2、扩充每个景点的邻接景点的方向等信息,使得路径查询结果能提供详尽的导向信息。
3、实现校园导游图的仿真界面。
1、具体函数
void DFS();步行深度优先搜索
void DFS1();乘车深度优先搜索
void Search();景点查询
void make_site();//景点介绍
void make_map();//数据地图化
void DIS();
void dijstra();//迪杰斯特拉算法
void mshort();//最短距离
void ashort();//所有路径
int menu();//菜单栏
void maps();//打印地图
void Floyd();//弗洛伊德算法
void Floyd_print();打印多景点最优路径
void Multispot();
2、程序实现
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX 0x3f3f3f
#define PP 999999
stack<int> S;
int dis[16],vis[16];
int dist[20][20];
int path[20],path1[20][20];
const int MAXV=1001,INF=1000001;
bool vest[MAXV];
int nex[MAXV],d[MAXV][MAXV];
int N,M,st,ed,cnt=0;
struct site //景点信息
{
int number; //编号
char name[20];//名称
char infor[100];//介绍
};
struct maps //景点的图
{
int point; //地点
int side; //边
site s[20];
int edge[20][20];
int edge_car[20][20];
} m;
void DFS(int i)
{
vest[i]=true;
if(i==ed)
{
cnt++;
printf("第%d条路径如下",cnt);
int k=st;
while(k!=ed)
{
printf("%d->",k);
k=nex[k];
}
printf("%d\n",k);
return;
}
for(int j=1; j<=m.point; j++)
{
if(vest[j]==false&&m.edge[i][j]!=MAX)
{
nex[i]=j;//对于路径0->1->3: nex[0]=1;nex[1]=3;
DFS(j);
vest[j]=false;
}
}
}
void DFS1(int i)
{
vest[i]=true;
if(i==ed)
{
cnt++;
printf("第%d条路径如下",cnt);
int k=st;
while(k!=ed)
{
printf("%d->",k);
k=nex[k];
}
printf("%d\n",k);
return;
}
for(int j=1; j<=m.point; j++)
{
if(vest[j]==false&&m.edge_car[i][j]!=MAX)
{
nex[i]=j;//对于路径0->1->3: nex[0]=1;nex[1]=3;
DFS1(j);
vest[j]=false;
}
}
}
void Search()
{
int i,n;
printf("山东工商学院东校区的景点有:\n");
printf("****************\n");
for(i=1; i<=14; i++)
{
printf("*******%d:%s\n",m.s[i].number,m.s[i].name);
}
printf("****************\n");
while(1)
{
printf("请输入你想要查询的景点编号:\n");
printf("按0退出\n");
scanf("%d",&n);
getchar();
if(n==0)
{
break;
}
else if(n<1||n>14)
{
printf("输入有误,请重新输入!!!\n\n");
continue;
}
else
{
printf("%d:%s\n",m.s[n].number,m.s[n].name);
printf("%s\n\n",m.s[n].infor);
}
}
return ;
}
void make_site()
{
int i;
for(i=1; i<=m.point; i++)
m.s[i].number=i;
strcpy(m.s[1].name,"实验楼");
strcpy(m.s[1].infor,"新建计科院楼");
strcpy(m.s[2].name,"逸夫楼");
strcpy(m.s[2].infor,"邵逸夫先生捐建");
strcpy(m.s[3].name,"家属楼");
strcpy(m.s[3].infor,"学校职工的住宅");
strcpy(m.s[4].name,"餐厅");
strcpy(m.s[4].infor,"山商东校餐厅");
strcpy(m.s[5].name,"大学生活动中心");
strcpy(m.s[5].infor,"举办文艺活动的场所");
strcpy(m.s[6].name,"图书馆");
strcpy(m.s[6].infor,"学校图书存放处、学生自习室");
strcpy(m.s[7].name,"宿舍");
strcpy(m.s[7].infor,"东校学生休息生活区");
strcpy(m.s[8].name,"办公楼");
strcpy(m.s[8].infor,"1--7楼为学生教室,8楼以上为学校办公场所");
strcpy(m.s[9].name,"四教");
strcpy(m.s[9].infor,"第四座教学楼");
strcpy(m.s[10].name,"二教");
strcpy(m.s[10].infor,"第二座教学楼");
strcpy(m.s[11].name,"东操场");
strcpy(m.s[11].infor,"东校田径运动场");
strcpy(m.s[12].name,"五教");
strcpy(m.s[12].infor,"第五座教学楼");
strcpy(m.s[13].name,"三教");
strcpy(m.s[13].infor,"第三座教学楼");
strcpy(m.s[14].name,"体育馆");
strcpy(m.s[14].infor,"室内篮球场以及各种赛事举办场");
}
void make_map()
{
int i,j;
m.point=14;
m.side=17;
for(i=0; i<=m.point; i++)
for(j=0; j<=m.point; j++)
{
m.edge[i][j]=MAX;
m.edge_car[i][j]=MAX;
}
/*memset(m.edge,MAX,sizeof(m.edge));
memset(m.edge_car,MAX,sizeof(m.edge_car));
fill(m.edge[0],m.edge[0]+20*20,MAX);*/
memset(dis,MAX,sizeof(dis));
memset(vis,0,sizeof(vis));
fill(vest,vest+MAXV,false);
fill(d[0],d[0]+MAXV*MAXV,INF);
d[0][2]=m.edge[1][3]=m.edge[3][1]=80;
d[1][2]=m.edge[2][3]=m.edge[3][2]=50;
d[2][3]=m.edge[3][4]=m.edge[4][3]=120;
d[2][4]=m.edge[3][5]=m.edge[5][3]=50;
d[4][5]=m.edge[5][6]=m.edge[6][5]=80;
d[4][7]=m.edge[5][8]=m.edge[8][5]=50;
d[4][8]=m.edge[5][9]=m.edge[9][5]=50;
d[5][9]=m.edge[6][10]=m.edge[10][6]=40;
d[7][8]=m.edge[8][9]=m.edge[9][8]=50;
d[8][9]=m.edge[9][10]=m.edge[10][9]=60;
d[3][6]=m.edge[4][7]=m.edge[7][4]=60;
d[6][9]=m.edge[7][10]=m.edge[10][7]=55;
d[6][10]=m.edge[7][11]=m.edge[11][7]=60;
d[6][13]=m.edge[7][14]=m.edge[14][7]=70;
d[9][12]=m.edge[10][13]=m.edge[13][10]=80;
d[11][12]=m.edge[12][13]=m.edge[13][12]=50;
d[12][13]=m.edge[13][14]=m.edge[14][13]=50;
d[0][2]=m.edge_car[2][4]=m.edge_car[4][2]=180;
m.edge_car[4][11]=m.edge_car[11][4]=160;
m.edge_car[11][14]=m.edge_car[14][11]=40;
m.edge_car[14][12]=m.edge_car[12][14]=120;
m.edge_car[12][8]=m.edge_car[8][12]=100;
}
void DIS(int a,int b,int c)//计算dis数组
{
memset(path,0,sizeof(path));
int i,j,pos=1,minn;
memset(vis,0,sizeof(vis));
for(i=1; i<=m.side; i++)
{
if(a==1)
dis[i]=m.edge[b][i];
if(a==2)
dis[i]=m.edge_car[b][i];
}
vis[b]=1;
dis[b]=0;
for(i=1; i<=m.point; i++)
{
minn=MAX;
for(j=1; j<=m.point; j++)
{
if(vis[j]==0&&minn>dis[j])
{
minn=dis[j];
pos=j;
}
}
vis[pos]=1;
for(j=1; j<=14; j++)
{
if(a==1)
{
if(vis[j]==0&&dis[j]>dis[pos]+m.edge[pos][j])
{
dis[j]=dis[pos]+m.edge[pos][j];
path[j]=pos;
}
}
if(a==2)
{
if(vis[j]==0&&dis[j]>dis[pos]+m.edge_car[pos][j])
{
dis[j]=dis[pos]+m.edge_car[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();
// for(i=1;i<=15;i++)
// cout<
// cout<
while(1)
{
if(x==0)
break;
S.push(x);
x=path[x];
}
S.push(b);
if(dis[c]>=100000)
printf("没有直达的路,请选择步行。\n");
else
{
printf("从%d到%d的最短路径为:",b,c);
while(!S.empty())
{
if(S.size()>1)
cout<<S.top()<<"->";
else
cout<<S.top();
S.pop();
}
printf("其最短距离为:%d",dis[c]);
}
}
void mshort()
{
int a,b,c;
printf("=====出行方式=====\n");
printf("1.步行\n");
printf("2.驾车\n");
printf("==================\n");
printf("选择出行方式\n");
scanf("%d",&a);
printf("输入起点\n");
scanf("%d",&b);
printf("输入终点\n");
scanf("%d",&c);
if((b<=0&&b>=16)||(c<=0&&c>=16))
{
printf("输入错误");
}
else
dijstra(b,a,c);
}
void ashort()
{
int a,b,c;
printf("=====出行方式=====\n");
printf("1.步行\n");
printf("2.驾车\n");
printf("==================\n");
printf("选择出行方式\n");
scanf("%d",&a);
printf("输入起点\n");
scanf("%d",&b);
printf("输入终点\n");
scanf("%d",&c);
if((b<=0&&b>=16)||(c<=0&&c>=16))
{
printf("输入错误");
}
else
{
st=b;
ed=c;
if(a==1)
DFS(st);
if(a==2)
DFS1(st);
}
}
int menu()
{
int n;
printf("\n");
printf(" ************欢迎使用山东工商学院导游系统***************\n\n");
printf(" * 1.山商景点信息查询 *\n");
printf(" * 2.两景点之间最短路查询 *\n");
printf(" * 3.两景点间所有路径查询 *\n");
printf(" * 4.多景点间访问路线查询 *\n");
printf(" * 5.退出系统 *\n");
printf(" *******************************************************\n");
printf("输入指令:\n");
scanf("%d",&n);
getchar();
return n;
}
void maps()
{
printf("\n *山商东校区校园景点地图*\n\n");
printf(" (14)体育馆 \n");
printf(" (12)五教 (13)三教 ◎ \n");
printf(" ◎ ◎--------------| (11)东操场 \n");
printf(" |-------------| | ◎ \n");
printf(" | | / \n");
printf(" 办 (9)四教 | | / \n");
printf(" 公 ◎ (10)二教 | | / \n");
printf(" (8) 楼◎--------|----------------------◎--------------| / \n");
printf(" \ | | ◎ \n");
printf(" \ | | (7) 宿舍 \n");
printf(" \ | ◎ | \n");
printf(" \ / |(6)图书馆 | \n");
printf(" |-----◎-------------------------| | \n");
printf(" (1)实验楼◎ | (5)大学生活动中心 | \n");
printf(" | | | \n");
printf(" |---------◎(3)家属楼--------------------------------------◎(4)餐厅 \n");
printf(" | \n");
printf(" (2)西校逸夫楼◎--| \n");
}
void Floyd()
{
int i,j,k;
for(i=1; i<=m.point; i++)
{
for(j=1; j<=m.point; j++)
{
dist[i][j]=m.edge[i][j];
if(i!=j&&dist[i][j]<PP)
{
path1[i][j]=i;
}
else
{
path1[i][j]=-1;
}
}
}
//printf("%d\n",g.n);
for(k=1; k<=m.point; k++)
{
for(i=1; i<=m.point; i++)
{
for(j=1; j<=m.point; j++)
{
if(dist[i][j]>(dist[i][k]+dist[k][j]))
{
dist[i][j]=dist[i][k]+dist[k][j];
path1[i][j]=k;
}
}
}
}
return ;
}
void Floyd_print(int s, int e)
{
if(path1[s][e]==-1||path1[s][e]==e||path1[s][e]==s)
{
return;
}
else
{
Floyd_print(s,path1[s][e]);
printf("%s->",m.s[path1[s][e]].name);
Floyd_print(path1[s][e],e);
}
}
void Multispot()
{
int vNum[20]= {0};
int i,j,dis1,a;
j=1;
dis1=0;
printf("请输入你要游览的第%d个景点的编号(输入-1结束输入):",j);
scanf("%d",&vNum[j]);
while(vNum[j]!=-1&&j<=14)
{
printf("请输入你要游览的第%d个景点编号:",++j);
scanf("%d", &vNum[j]);
if(vNum[j]!=-1)
a=vNum[j];
if(vNum[j]==-1)
{
break;
}
}
printf("\n这是最佳访问路径:");
for(i=0; vNum[i+1]>0&&vNum[i+2]>0; i++)
{
printf("%s->",m.s[vNum[i+1]].name);
Floyd_print(vNum[i+1],vNum[i+2]);
dis1+=dist[vNum[i+1]][vNum[i+2]];
}
printf("%s\n\n",m.s[a].name);
printf("全程总长为:%dm\n\n",dis1);
}
int main()
{
int n;
maps();
make_map();
make_site();
while(1)
{
n=menu();
if(n<1||n>5)
printf("输入错误,请重新输入\n");
else
{
if(n==1)
Search();
else if(n==2)
mshort();
else if(n==3)
ashort();
else if(n==4)
{
maps();
Floyd();
Multispot();
}
else if(n==0)
break;
}
}
}
3、总结
校园导游系统,可以查看校园景点图,可以查看景点的信息,道路也分为人行道和车行道,还可以查找两景点间的最短路径和所有路径,还可以根据想去看的所有景点推荐一个最佳路径。程序中用了最短路算法和最小生成树算法,还有深搜算法。