课程设计旅游景点咨询系统

来源:互联网 发布:aptget升级软件 编辑:程序博客网 时间:2024/04/18 15:38

欢迎访问我的网站:omegaxyz.com
问题描述:创建一个至少有15个点的有向网表示的某个旅游景点的导游图。顶点代表景点,类型为字符串(例如,泰山导游图:“天地广场门”,“十八盘”,“冯玉祥墓”,“桃花峪门”,“中天门”,“南天门”,“玉皇顶”等),弧表示两个景点之间可以直达,弧上的权值表示两个景点之间的路程(公里数),弧上还有到达方法的信息(有步行和索道两种)。建立一个游客咨询系统。

1.基本要求

(1)创建图的存储结构。
(2)输入两个景点名,就可以得到从一个景点到达另一个景点的所有简单路径、相应路径的路程公里数、行走的方法(每一段是步行,还是坐索道);
(3)输入两个景点名,就可以得到其最短路径,即:路程最短的行进方法;如果两者无路径可通,就得出“两景点不可达的信息”。

2.重点、难点

重点:
(1)通过实验掌握图状结构数据的存储与表式;
(2)通过实验掌握对图的存储、遍历、运算等各种操作;
(3)深入理解图的特征及应用;
难点:
(1)任意两个景点所有路径的计算;
(2)最短路径的计算与算法设计。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>#define N 15#define MAX 999int min_len[N];int route[N][N];int visited[N];int flag[N];int stack[N];int path[N][N];int temp[N][N];int start=99,end=99;int v,w,m=1;int static n=0;typedef struct{    char name[N][20];    int length[N][N];    char way[N][N];}Point;void init_path(){    int i,k;    for(i=0;i<N;i++)    {        path[i][0]=start;path[i][1]=i;        for(k=2;k<N;k++)            path[i][k]=999;    }}void read_file(Point *info){    int i=0,j;    char ch[N][10];    FILE *fp1,*fp2,*fp3;    if((fp1=fopen("view_name.txt","r"))==NULL){        printf("Open failed!!!\n");exit(0);    }    if((fp2=fopen("view_length.txt","r"))==NULL){        printf("can not open file!");        exit(0);    }    if((fp3=fopen("view_way.txt","r"))==NULL){        printf("can not open file!");        exit(0);    }    for(i=0;i<N;i++)        fscanf(fp1,"%s",&info->name[i]);    fclose(fp1);    for(i=0;i<N;i++){        for(j=0;j<N;j++){            fscanf(fp2,"%d",&info->length[i][j]);            temp[i][j]=info->length[i][j];        }    }    fclose(fp2);    for(i=0;i<N;i++){        for(j=0;j<N;j++)            fscanf(fp3,"%c",&info->way[i][j]);    }    fclose(fp3);}void output_view(Point *info){    int i,j;    printf("一共有%d个景点,关系如下:\n\n     ",N);    for(i=0;i<N;i++)        printf("%-7s",info->name[i]);    printf("\n");    for(i=0;i<N;i++)        for(j=0;j<=N;j++)        {            if(j==0)printf("%-3s",info->name[i]);            if(j!=N)printf("%4d(%c)",info->length[i][j],info->way[i][j]);            else printf("\n");        }}void Dijkstra(Point *info){    int i=1,j,min;    for(v=0;v<N;v++)                //循环初始化    {        flag[v]=0;        min_len[v]=info->length[start][v];        for(w=0;w<N;w++)            route[v][w]=0;              //设空路径        if(min_len[v]<MAX)        {            route[v][start]=1;            route[v][v]=1;        }     }    min_len[start]=0;    flag[start]=0;         //初始化start顶点属于集合S    for(i=1;i<N;i++)        //开始主循环 每次求得v0到某个顶点v的最短路径 并加v到集合S中    {        min=MAX;        for(w=0;w<N;w++)        if(!flag[w])       //如果w顶点在V-S中        {                            //这个过程最终选出的点 应该是选出当前V-S中与S有关联边                            //且权值最小的顶点 书上描述为当前离start最近的点            if(min_len[w]<min)            {                v=w;                min=min_len[w];            }        }        flag[v]=1;                                 //选出该点后加入到合集S中        for(w=0;w<N;w++)                            //更新当前最短路径和距离        {            if(!flag[w]&&(min+info->length[v][w]<min_len[w]))            {                for(j=0;j<N;j++)                    path[w][j]=path[v][j];                for(j=0;j<N;j++)                    if(path[w][j]==999) {path[w][j]=w;break;}            min_len[w]=min+info->length[v][w];            route[w][w]=1;        }    }    }}void DFS(Point *info,int p){    int i,j,len;    visited[p]=1;    for(i=0;i<N;i++)    {        if(info->length[p][i]!=MAX)        {            if(i==end)            {                n++;printf("第%d条: ",n);                for(j=0;j<m;j++)                {                    stack[m]=end;                    //printf("(%d,%s,%c)-->",stack[j]+1,info->name[stack[j]],info->way[stack[j]][stack[j+1]]);                    printf("(%s)---%c--->",info->name[stack[j]],info->way[stack[j]][stack[j+1]]);                }                //printf("%d(%s)\n\n",end+1,info->name[end]);                printf("(%s)\n\n",info->name[end]);            }            else if(!visited[i])            {                info->length[p][i]=MAX;                visited[i]=1;                stack[m]=i;                m++;                DFS(info,i);                info->length[p][i]=temp[p][i];                visited[i]=0;                m--;            }        }    }}void receive(Point *info){    int i;    char a[20],b[20];    printf("\n输入起点和终点标号,按# #退出:");scanf("%s%s",a,b);    printf("得出所有简单路径和最短路径\n");    if(strcmp(a,"#")==0&&strcmp(b,"#")==0)return;    for(i=0;i<N;i++)    {        if(strcmp(a,info->name[i])==0)start=i;        if(strcmp(b,info->name[i])==0)end=i;    }    init_path();    //for(i=0;i<N;i++)printf(" %d ",min_len[i]);    if(start==99||end==99)printf("输入错误,请重新输入景点名\n");    else    {        Dijkstra(info);        //for(i=0;i<N;i++)printf(" %d ",min_len[i]);        //printf("@%d %d %d",start,end,min_len[end]);        if(min_len[end]!=MAX)        {            printf("景点%s到景点%s最短路径长度为:%d\n所有简单路径:\n",                        info->name[start],info->name[end],min_len[end]);            for(i=0;i<N;i++)                visited[i]=0;            stack[0]=start;            DFS(info,start);            printf("一共有%d条路径!\n",n);            printf("景点%s到景点%s最短路径长度为:%d\n",                        info->name[start],info->name[end],min_len[end]);            printf("最短路径为: ");            for(i=0;i<N;i++)            {                if(path[end][i+1]==999)break;                //printf("(%d,%s)--%c-->",path[end][i]+1,info->name[path[end][i]],info->way[path[end][i]][path[end][i+1]]);                printf("(%s)---%c--->",info->name[path[end][i]],info->way[path[end][i]][path[end][i+1]]);            }            //printf("%d(%s)\n",path[end][i]+1,info->name[path[end][i]]);            printf("(%s)\n",info->name[path[end][i]]);        }        else {printf("\n非常抱歉!!!景点%s无法到达%s",info->name[start],info->name[end]);}        printf("\n");    }    start=end=99;n=0;}int main(){    int i,j=0;    char x;    Point *view_info=NULL;    view_info=(Point *)malloc(sizeof(Point));    read_file(view_info);    msgbox(view_info);    printf("输入操作:");    while(scanf("%c",&x)!=EOF)    {        switch(x)        {            case 'S':msgbox(view_info);receive(view_info);printf("输入操作:");break;            case 'E':exit(0);            default :cur_sys();msgbox(view_info);printf("输入操作:");continue;        }    }    printf("谢谢使用!!!");}

这里写图片描述
这里写图片描述

原创粉丝点击