河北大学校园导航

河北大学校园导航

【问题描述】

以我校为例,设计一个校园导航系统,主要为来访的客人提供信息查询。系统有两类登陆账号,一类是游客,使用该系统方便校内路线查询;一类是管理员,可以使用该系统查询校内路线,可对校园景点路线可编辑。

【需求分析】

设计学校的平面图,至少包括10个以上景点(场所),每两个景点间可以有不同道路,且路长也可能不同,找出在游人所在景点到其他景点的最短路径,或游人输入的任意两个景点的最短路径。 要求: (1) 以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,路径权重为路径长度。 (2) 为游人提供任意景点相关信息查询。 (3)为游人提供任意景点的问路查询,即任意两个景点之间的最短路径。

在这里插入图片描述
实现提示: 一般情况下,校园道路是双向通行的,可设计校园平面图是一个无向图。顶点和边均含有相关信息。 选做内容: (1)提供图的编辑功能:增删景点;增删道路;修改已有信息等。 (2)校园导游图的仿真界面。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
后续操作自行操作即可

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define INF 9999
typedef   struct
{
    char name[20];
    char features[100];
} Vertex;
//矩阵结构体
typedef struct
{
    Vertex vexs[100];
    int edges[500][500];
    int n,e;//点和边数
} Graph;

//构造图的矩阵存储
void create(Graph *G )
{
    int i,j;
    G->n=12;
    G->e=20;
    char str_name[50][50]= {"体检中心","邯郸音乐厅","网计学院","信息学部","操场","图书馆",
                            "花园景观","校门南口","校门北口","校门东口","银杏景观","餐厅"
                           };
    char str_features[100][200]= {"学校的用于学生体检地","学校用于举办大型音乐会的地方","C1楼","信息学部","操场","图书馆","用于观赏",
                                  "校门南口","校门北口","校门东口","种植了许多银杏树","餐厅"
                                 };
    for(i=0; i<G->n; i++)//节点信息初始化
    {
        strcpy(G->vexs[i].name,str_name[i]);
        strcpy(G->vexs[i].features,str_features[i]);
    }
    for(i=0; i<500; i++)
        for(j=0; j<500; j++)
            G->edges[i][j]=INF;
    G->edges[1][0]=G->edges[0][1]=200;
    G->edges[4][0]=G->edges[0][4]=350;
    G->edges[1][2]=G->edges[2][1]=500;
    G->edges[2][7]=G->edges[7][2]=400;
    G->edges[1][4]=G->edges[4][1]=480;
    G->edges[1][5]=G->edges[5][1]=400;
    G->edges[1][3]=G->edges[3][1]=500;
    G->edges[7][3]=G->edges[3][7]=400;
    G->edges[6][3]=G->edges[3][6]=150;
    G->edges[7][6]=G->edges[6][7]=500;
    G->edges[7][9]=G->edges[9][7]=600;
    G->edges[4][5]=G->edges[5][4]=280;
    G->edges[4][8]=G->edges[8][4]=200;
    G->edges[5][6]=G->edges[6][5]=160;
    G->edges[5][9]=G->edges[9][5]=300;
    G->edges[6][9]=G->edges[9][6]=200;
    G->edges[9][11]=G->edges[11][9]=100;
    G->edges[8][11]=G->edges[11][8]=100;
    G->edges[8][10]=G->edges[10][8]=100;
    G->edges[10][11]=G->edges[11][10]=100;
}
//遍历景点
int ergodic(Graph *G,int v)
{
    int i;
    for(i=0; i<G->n; i++)
    {
        if(i==v)
            return v;
    }
    return -1;
}
void display(Graph *G)
{
    int k=-1;
    int i,j;
    printf("\n\n");
    for( i=0;i<=G->n;i++){
            printf("\n");
        for(j=0;j<=G->n;j++){
            if(G->edges[i][j]<INF){
                    printf("%d     ",G->edges[i][j]);
                }else if(i==j)
                {
                    printf("  0     ");
                }
                else{
                    printf(" ∞     ");
                }
        }
    }
    printf("\n\n");
}
//任意景点的介绍
Vertex GetVex(Graph *G, int v)
{
    int j;
    j=ergodic(G,v);
    if(j==-1)
    {
        printf("                        无此景点\n\n\n\n");
        Sleep(1000);
        return ;
    }
    else
    {
        printf("%s",G->vexs[v].name);
        Vertex a=G->vexs[j];
        return a;
    }
}
//修改景点信息
void PutVertex(Graph *G, int v)
{
    int j;
    j=ergodic(G,v);
    if(j==-1)
    {
        printf("                         无此景点\n\n\n\n\n");
        Sleep(1000);
    }
    else
    {
        char s[100];
        printf("\n");
        printf("                         请输入修改后的信息:\n\n");
        printf("                         ");
        scanf("%s",s);
        strcpy(G->vexs[j].features,s);
        printf("\n");
        printf("                         修改成功\n\n\n\n\n");
    }
}
//增加景点
void InsertVertex(Graph*G, Vertex v)
{
    char str_name[20],str_features[100];
    int num,edge,a[100],i,a1[100],b;
    printf("                       请输入景点名称:\n\n");
    printf("                            ");
    scanf("%s",str_name);
    strcpy(v.name,str_name);
    printf("\n");
    printf("                       请输入景点介绍:\n\n");
    printf("                            ");
    scanf("%s",str_features);
    strcpy(v.features,str_features);
    printf("\n");
    printf("                       请输入新增景点的边数:\n\n");
    printf("                            ");
    scanf("%d",&edge);
    printf("\n");
    printf("                       请输入与新增景点连通的景点编号以及路径长度:\n\n");
    G->e+=edge;
    G->n=G->n+1;
    G->vexs[G->n-1]=v;
    for(i=0; i<G->n; i++)
        G->edges[G->n-1][i]=G->edges[i][G->n-1]=9999;//初始化
    for(i=0; i<edge; i++)
    {
        printf("                            ");
        scanf("%d %d",&a1[i],&b);//编号和长度
        a[i]=ergodic(G,a1[i]);
        G->edges[G->n-1][a[i]]=G->edges[a[i]][G->n-1]=b;
        printf("\n");
    }
}
//删除景点,删除路
//判断是否有该点
void DeleteVertex(Graph *G, int h)
{
    int a,b=0,i;
    if(h==-1)
    {
        printf("                         无此景点\n\n\n\n\n");
        Sleep(1000);
    }
    else
    {
        strcpy(G->vexs[h].features,"");
        strcpy(G->vexs[h].name,"");
        for(i=0; i<G->n; i++)
        {
            if(G->edges[h][i]!=INF||G->edges[h][i]!=0)
            {
                G->edges[h][i]=G->edges[i][h]=INF;
                b++;
            }
        }
    }
}
//增加道路
void InsertArc(Graph *G,int v, int w)
{
    int length;
    printf("                       请输入新加道路的长度:\n\n");
    printf("                            ");
    scanf("%d",&length);
    int a=ergodic(G,v);
    int b=ergodic(G,w);
    G->edges[a][b]=G->edges[b][a]=length;
}
//删除道路
void DeleteArc(Graph*G,int v,int w)
{
    int a=ergodic(G,v);
    int b=ergodic(G,w);
    if(a==-1||b==-1)
    {
        printf("                         无此景点\n\n\n\n\n");
        Sleep(1000);
    }
    else
        G->edges[a][b]=G->edges[b][a]=9999;
}
void floyd(Graph *G,int path[][20],int dist[][20])
{
    int start,end;
    int i,j,k;
    int tmp;
    printf("请输入你所在位置的编号:");
    scanf("%d",&start);
    printf("请输入你要去位置的编号:");
    scanf("%d",&end);
    for(i=0;i<G->n;i++)
    {
        for(j=0;j<G->n;j++)
        {
            dist[i][j]=G->edges[i][j];
            path[i][j]=j;
        }
    }
    for(k=0;k<G->e;k++)
    {
        for(i=0;i<G->e;i++)
        {
            for(j=0;j<G->e;j++)
            {
                tmp=(dist[i][k]==INF||dist[k][j]==INF)?INF:(dist[i][k]+dist[k][j]);
                if(dist[i][j]>tmp)
                {
                    dist[i][j]=tmp;
                    path[i][j]=k;
                }
            }
        }
    }

    printf("\n    ★★★%s--->%s的最短路径长度为: %2d",G->vexs[start].name,G->vexs[end].name,dist[start][end]);
    printf("\n    路径为:%s",G->vexs[end].name);
    if(path[start][end]==end) printf("->%s\n",G->vexs[start].name);
    else{
        k=end;
        while(path[start][k]!=k)
        {
            k=path[start][k];
            printf("->%s\n",G->vexs[k].name);

        }
    }
}
//根据地点名确定地点序号
int Locate(Graph *G, char name[])
{
    int i;
    for(i = 0; i < G->n; i++){
        //图中含有该景点,找到其序号
        if(!strcmp(G->vexs[i].name, name))
            return i;
    }
    return -1;
}

//查询任意两景点间的最短路径
void Dij_Short_Path(Graph *G)
{
    char name[50], choice = 'y';	//
    int start, end;
    int dist[20+1];
    printf("\t\t\t\t\t  最短路径...\n\n\n\n");
    while(choice == 'y' || choice == 'Y'){
        int path[20+1][20+1] = {0};
        printf("\n\t\t\t\t\t请输入起点:");
        scanf("%s", name);
        start = Locate(G, name);
        while(start == -1)
		{
			printf("\t\t\t\t无效输入,请重新输入:");
			scanf("%s", name);
			start = Locate(G,name);
		}
        printf("\t\t\t\t\t请输入终点:");
        scanf("%s", name);
        end = Locate(G, name);
        while(end == -1)
		{
			printf("\t\t\t\t无效输入,请重新输入:");
			scanf("%s", name);
			end = Locate(G,name);
		}
        Dijkstra(G, start, end, dist, path);
        printf("\t\t\t\t\t是否继续查询(y || n):");
        getchar();
        choice = getchar();
    }
}
//采用Dijkstra算法求单元点的最短路径
void Dijkstra(Graph *G, int start, int end, int dist[], int path[][20+1])
{
    int mindist, i, j, k, t = 1;

    //初始化
    for(i = 1; i <= G->n; i++){
        dist[i] = G->edges[start][i];		//读入开始行的邻接信息
        if(G->edges[start][i] != INF)
            path[i][1] = start;
    }
    path[start][0] = 1;

    //寻求最短路径
    for(i = 2; i <= G->n; i++){
        mindist = INF;
        for(j = 1; j <= G->n; j++){
            if(!path[j][0] && dist[j] < mindist){
                mindist = dist[j];
                k = j;
            }
        }
        if(mindist == INF)  break;
        path[k][0] = 1;

        //修改加入后的最短路径
        for(j = 1; j <= G->n; j++){
            if(!path[j][0] && G->edges[k][j] < INF && G->edges[k][j] + dist[k] < dist[j]){
                dist[j] = dist[k] + G->edges[k][j];

               //记录最短路径
                t = 1;
                while(path[k][t]){
                    path[j][t] = path[k][t];
                    t++;
                }
                path[j][t] = k;
                path[j][t+1] = 0;
            }
        }
    }
    if(dist[end] == INF){
        printf("\n\n\t%s----->%s  不存在通路!!!\n", G->vexs[start].name, G->vexs[end].name);
        return;
    }
    //输出最短路径
    printf("\n\n\t%s----->%s", G->vexs[start].name, G->vexs[end].name);
    printf("\n\t距离为:%dm\n", dist[end]);

}
void Floyd(Graph *G)
{
 int v,u,i,w,k,j,flag=1,p[20][20][20],D[20][20];
 for(v=0;v<G->n;v++)
  for(w=0;w<G->n;w++)
  {
   D[v][w]=G->edges[v][w];
   for(u=0;u<G->n;u++)
    p[v][w][u]=0;
   if(D[v][w]<INF)
   {
    p[v][w][v]=1;
    p[v][w][w]=1;
   }
  }
 for(u=0;u<G->n;u++)//中转点
  for(v=0;v<G->n;v++)//源点
   for(w=0;w<G->n;w++)//终点
    if(D[v][u]+D[u][w]<D[v][w])//不满足三角不等式就更新距离
    {
     D[v][w]=D[v][u]+D[u][w];
     for(i=0;i<G->n;i++)
      p[v][w][i]=p[v][u][i]||p[u][w][i];
    }

 while(flag)
 {
  printf("请输入出发点和目的地的编号:");
  scanf("%d %d",&k,&j);
  if(k<0||k>G->n||j<0||j>G->n)//判断输入是否合法
  {
  printf("景点编号不存在!请重新输入出发点和目的地的编号:");
     scanf("%d %d",&k,&j);
  }
  if(k>=0&&k<G->n&&j>=0&&j<G->n)
   flag=0;
 }
 printf("%s",G->vexs[k].name);
 for(u=0;u<G->n;u++)
  if(p[k][j][u]&&k!=u&&j!=u)
   printf(" *** %s",G->vexs[u].name);//输出到某个点的最短路径
 printf(" *** %s",G->vexs[j].name);
 printf(" 总路线长%dm\n",D[k][j]);
}

int  show()
{
    printf("                                         管理员页面                               \n");
    printf("                                        1.景点介绍                               \n\n");
    printf("                                        2.修改景点信息                           \n\n");
    printf("                                        3.增加景点                               \n\n");
    printf("                                        4.删除景点                               \n\n");
    printf("                                        5.增加道路                               \n\n");
    printf("                                        6.删除道路                               \n\n");
    printf("                                        7.查找任意两个景点的最短路径             \n\n");
    printf("                                        8.查看校园路径                           \n\n");
    printf("                                        9.查看校园导航仿真图                     \n\n");
    printf("                                        10.退出导航                               \n\n");
    printf("请选择相应的功能:                          ");
    int data;
    scanf("%d",&data);
    return data;
}

int show_1()
{
    printf("                                          游客页面                               \n");
    printf("                                        1.景点介绍                               \n\n");
    printf("                                        2.查找任意两个景点的最短路径             \n\n");
    printf("                                        3.查看校园导航仿真图                     \n\n");
    printf("                                        4.退出导航                               \n\n");
    printf("请选择相应的功能:                          ");
    int data;
    scanf("%d",&data);
    return data;
}
void show0(Graph *G)
{
    int i;
    for(i=0;i<G->n;i++)
    {
        printf("                               %d->%s\n",i,G->vexs[i].name);
    }
}
void show3()
{
    printf("体检中心(0)------------操场(4)------校门北口(8)-----银杏景观(10)\n");
    printf("    \\                   /  \\                \\           /\n");
    printf("     \\                 /    \\                \\         /\n");
    printf("      \\               /    图书馆(5)          \\       /\n");
    printf("       \\             /______/  |    \\          \\     /\n");
    printf("        邯郸音乐厅(1)          |     \\          餐厅(11) \n");
    printf("         |     \\               |      \\_______     /\n");
    printf("         |      \\        花园景观(6)----------校门东口(9)\n");
    printf("         |       \\        /     |                  /\n");
    printf("         |     信息学部(3)      |                 /\n");
    printf("         |          \\           |                /\n");
    printf("         |           \\          |               /\n");
    printf("         |            \\         |              /\n");
    printf("       网计学院(2)     \\        |             /\n");
    printf("          \\             \\       |            /\n");
    printf("           \\             \\      |           /\n");
    printf("            \\__________   \\     |      ____/\n");
    printf("                         校门南口(7)\n");
    printf("\n\n");
}
int main()
{

    Graph G;
    create(&G);
    int a;
    int i;
    printf("河北大学欢迎您!\n");
    printf("                               所有人请注意!\n");
    printf("                    后续操作如需输入编号,请记清下面各地点编号!\n");
    show0(&G);
    printf("欢迎使用本次导航系统,祝您愉快!\n");
    printf("请输入您的账号:(管理员为111,游客为222)\n");
    int v,w;
    scanf("%d",&a);
    if(a==111)
    {
        int data;
       while(1)
                {

                    data=show();
                    printf("\n");
                    if(data==1)
                    {
                        printf("                       请输入要查询的景点编号:       ");
                        int v;
                        scanf("%d",&v);
                        Vertex a=GetVex(&G,v);
                        printf("**************");
                        printf("%s\n\n\n\n",a.features);
                    }
                    else if(data==2)
                    {
                        //display(&G);
                        int nold;
                        printf("                       请输入要修改信息的景点编号:       ");
                        scanf("%d",&nold);
                        system("cls");
                        PutVertex(&G,nold);
                    }
                    else if(data==3)
                    {
                        Vertex d;
                        InsertVertex(&G,d);
                        printf("\n\n\n\n");
                        printf("                                           景点添加成功\n\n\n\n");
                    }
                    else if(data==4)
                    {
                        int h;
                        printf("                       请输入要删除景点序号:\n\n");
                        printf("                            ");
                        scanf("%d",&h);
                        DeleteVertex(&G,h);
                        printf("\n\n\n\n");
                        printf("                                           景点删除成功\n\n\n\n");
                    }
                    else if(data==5)
                    {
                        int v,w;
                        printf("                       请输入与新增路连接的两个景点编号:\n\n");
                        printf("                            ");
                        scanf("%d %d",&v,&w);
                        InsertArc(&G,v,w);
                        printf("\n\n\n\n");
                        printf("                                            道路添加成功\n\n\n\n");

                    }
                    else if(data==6)
                    {
                        int v1,w1;
                        printf("                       请输入与要删除路连接的两个景点编号:\n\n");
                        printf("                            ");
                        scanf("%d %d",&v1,&w1);
                        DeleteArc(&G,v1,w1);
                        printf("\n\n\n\n");
                        printf("                                            道路删除成功\n\n\n\n");
                    }

                    else if(data==7)
                    {

                        system("cls");
                        Dij_Short_Path(&G);
                        printf("\n\n");
                    }
                    else if(data==8)
                    {
                        display(&G);
                    }
                    else if(data==9)
                    {
                        show3();
                    }
                    else if(data==10)
                    {
                        //exit(0);
                        int data;
        int dist[20],path[20][20];
       while(1)
                {
                    data=show_1();
                    printf("\n");
                    if(data==1)
                    {
                        printf("                       请输入要查询的景点编号:       ");
                        int v;
                        scanf("%d",&v);
                        Vertex a=GetVex(&G,v);
                        printf("**************");
                        printf("%s\n\n\n\n",a.features);
                    }
                    else if(data==2)
                    {
                        system("cls");
                        Floyd(&G);
                        printf("\n\n");
                    }
                    else if(data==3)
                    {
                        show3();
                    }
                    else if(data==4)
                    {
                        exit(0);
                    }

                }

                    }
                }

  }

    if(a==222)
    {
        int data;
        int dist[20],path[20][20];
       while(1)
                {
                    data=show_1();
                    printf("\n");
                    if(data==1)
                    {
                        printf("                       请输入要查询的景点编号:       ");
                        int v;
                        scanf("%d",&v);
                        Vertex a=GetVex(&G,v);
                        printf("**************");
                        printf("%s\n\n\n\n",a.features);
                    }
                    else if(data==2)
                    {
                        system("cls");
                        Floyd(&G);
                        printf("\n\n");
                    }
                    else if(data==3)
                    {
                        show3();
                    }
                    else if(data==4)
                    {
                        exit(0);
                    }

                }

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值