数据结构实训——校园导航系统

设计一个校园导游系统,为来访的客人提供各种信息查询服务。(限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;
}

你可能感兴趣的:(数据结构实训——校园导航系统)