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

41 篇文章 4 订阅
38 篇文章 2 订阅

欢迎访问我的网站: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 999

int 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("谢谢使用!!!");
}

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值