C语言课程设计之旅游景点咨询系统

C语言课程设计之旅游景点咨询系统

1.问题描述:创建一个至少有15个点的有向网表示的某个旅游景点的导游图。顶点代表景点,类型为字符串(例如,泰山导游图:“天地广场门”,“十八盘”,“冯玉祥墓”,“桃花峪门”,“中天门”,“南天门”,“玉皇顶”等),弧表示两个景点之间可以直达,弧上的权值表示两个景点之间的路程(公里数),弧上还有到达方法的信息(有步行和索道两种)。建立一个游客咨询系统。
2.基本要求
(1)创建图的存储结构。
(2)输入两个景点名,就可以得到从一个景点到达另一个景点的所有简单路径、相应路径的路程公里数、行走的方法(每一段是步行,还是坐索道);
(3)输入两个景点名,就可以得到其最短路径,即:路程最短的行进方法;如果两者无路径可通,就得出“两景点不可达的信息”。
(4)按照题意要求独立进行设计,设计结束后按要求写出设计报告。

一、代码块:

#include<bits/stdc++.h>
/*#include<iostream>
#include<fstream>
#include<algorithm>
#include<stack>*/
using namespace std;
const int MAXVEX=50;
const int INF=0x3fffffff;
//s表示索道 w表示步行

typedef struct{//边的结构
    int wei;//权值
    char way;//到达方式
}EdgeType;

typedef struct{
    string vexs[MAXVEX];//顶点信息,string类型
    EdgeType arc[MAXVEX][MAXVEX];//边的信息
    int numVertexes,numEdges;//顶点数和边数
}MGraph;

void CreateMGraph(MGraph *G)
{
    FILE *fp;
    fp=fopen("read.txt","r");
    int i,j,k,w;
    cout<<"请输入顶点数和边数"<<endl;
    //cin>>G->numVertexes>>G->numEdges;
    fscanf(fp,"%d %d",&G->numVertexes,&G->numEdges);
    cout<<"请输入"<<G->numVertexes<<"个景点名"<<endl;
    char temp[MAXVEX];
    for(i=0;i<G->numVertexes;++i){
        fscanf(fp,"%s",temp);//cin>>G->vexs[i];
        G->vexs[i]=temp;
    }
    //初始化邻接矩阵
    for(i=0;i<G->numVertexes;++i)
        for(j=0;j<G->numVertexes;++j)
            G->arc[i][j].wei=INF;
    cout<<"请输入"<<G->numEdges<<"条边,包括起点下标、终点下标、路程(KM)和到达方式(s表示索道 w表示步行)"<<endl;
    for(k=0;k<G->numEdges;++k){
        char ch;
        fscanf(fp,"%d %d %d %c",&i,&j,&w,&ch);//cin>>i>>j>>w>>ch;
        G->arc[i][j].wei=w;
        G->arc[i][j].way=ch;
    }
    cout<<endl<<"*******邻接矩阵建立完成,各景点对应的编号如下*******"<<endl<<endl;
    for(i=0;i<G->numVertexes;++i){
        cout<<"编号"<<i<<" "<<G->vexs[i]<<endl;
    }
}

int solution[MAXVEX];//记录路线
bool vis[MAXVEX];//标记数组
int flag;//通路标记

void print(MGraph G,int len)//参数为路径上的第几个点
{
    flag=1;
    int sum=0;
    cout<<G.vexs[solution[1]];
    for(int i=2;i<=len;++i){//第一个点已经打印,打印剩下的点
        if(G.arc[solution[i-1]][solution[i]].way=='s') cout<<" -> "<<"(索道)"<<G.vexs[solution[i]];
        else cout<<" -> "<<"(步行)"<<G.vexs[solution[i]];
        sum+=G.arc[solution[i-1]][solution[i]].wei;
    }
    cout<<endl<<"该路径总路程为"<<sum<<"KM"<<endl;
    cout<<endl;
}

void dfs(MGraph G,int k,int loc,int e)//k为第几步,loc为当前的位置,e为目标
{
    solution[k]=loc;//当前顶点加入路线
    vis[loc]=1;//标记置为1
    if(loc==e) print(G,k);
    else
    for(int i=0;i<G.numVertexes;++i){
        if(vis[i]==0&&G.arc[loc][i].wei<INF) dfs(G,k+1,i,e);
    }
    vis[loc]=0;//取消标记
}

void slove_allpath(MGraph G,int s,int e)//查找所有可行路径
{
    flag=0;//有无路径标记
    memset(vis,0,sizeof(vis));
    dfs(G,1,s,e);//从第一步起点开始
    if(!flag) cout<<"无可行路径!"<<endl;
}

int P[MAXVEX][MAXVEX];//用于存储最短路径下标的数组
int D[MAXVEX][MAXVEX];//用于存储到各点最短路径的权值之和

void ShortestPath_Dijkstra(MGraph G,int v0)//最短路求解
{
    int v,w,k,Min;
    int Final[MAXVEX];//标记,=1表示求得顶点V0至Vw的最短路径
    for(v=0;v<G.numVertexes;v++){//初始化数据
        Final[v]=0;//全部顶点初始化为未知最短路径状态
        D[v0][v]=G.arc[v0][v].wei;//将与V0有连线的顶点加上权值
        P[v0][v]=v0;//初始化路径数组pre顶点均为起始点V0
    }
    D[v0][v0]=0;//v0至v0路径为0
    Final[v0]=1;//v0至v0不需要求路径
    for(v=1;v<G.numVertexes;v++){
        Min=INF;//初始化最小值为INF
        for(w=0;w<G.numVertexes;w++){
            if(!Final[w]&&D[v0][w]<Min){
                k=w;
                Min=D[v0][w];//w顶点离v0顶点更近
            }
        }
        Final[k]=1;//将目前找到的最近的顶点位置置为1
        for(w=0;w<G.numVertexes;++w){//修正当前最短路径及距离
            //如果经过v顶点的路径比现在这条路径的长度短的话
            if(!Final[w]&&(Min+G.arc[k][w].wei<D[v0][w])){
                D[v0][w]=Min+G.arc[k][w].wei;//修改当前路径长度
                P[v0][w]=k;
            }
        }
    }
}

stack<int> xiang;//辅助栈

void slove_ShortestPath(MGraph G,int s,int e)//查找最短路径
{
    int tempe=e;
    if(D[s][e]==INF) cout<<"无可行路径!"<<endl;
    else{//有最短路径
        int temp=D[s][e];
        xiang.push(e);//终点先进栈
        while(P[s][e]!=s)//根据P数组倒着找
        {//只要不到起点
            xiang.push(P[s][e]);
            e=P[s][e];
        }
        //cout<<"由"<<G.vexs[s]<<"到"<<G.vexs[tempe]<<"的最短路径为:"<<endl;
        cout<<G.vexs[s];
        int pre=s;
        while(!xiang.empty())
        {
            int top=xiang.top();
            if(G.arc[pre][top].way=='s') cout<<" -> "<<"(索道)"<<G.vexs[top];
            else cout<<" -> "<<"(步行)"<<G.vexs[top];
            pre=top;
            xiang.pop();
        }
        cout<<endl<<"该路径总路程为"<<temp<<"KM"<<endl;
    }
    cout<<endl;
}

int main()
{
    MGraph G;
    CreateMGraph(&G);
    for(int i=0;i<G.numVertexes;++i) ShortestPath_Dijkstra(G,i);
    /*
    for(int i=0;i<G.numVertexes;++i){
        for(int j=0;j<G.numVertexes;++j)
            cout<<P[i][j]<<' ';
    cout<<endl;
    }
    cout<<endl;
     for(int i=0;i<G.numVertexes;++i){
        for(int j=0;j<G.numVertexes;++j)
            cout<<D[i][j]<<' ';
    cout<<endl;
    }
    */
    cout<<"请输入需要查找的路径(对应的起点和终点下标),输入-1结束查找"<<endl;
    int s,e;
    while(cin>>s>>e&&(s+e)>=0)
    {
        if(s==e){
            cout<<"您已在该景点"<<endl;
            continue;
        }
        cout<<"*******由"<<G.vexs[s]<<"到"<<G.vexs[e]<<"可行的路径有:*******"<<endl;
        slove_allpath(G,s,e);//查找所有可行路径
        cout<<"*******由"<<G.vexs[s]<<"到"<<G.vexs[e]<<"的最短路径为:*******"<<endl;
        slove_ShortestPath(G,s,e);//查找最短路径
    }
    cout<<"********************查 找 结 束********************"<<endl;
    return 0;
}

二、运行:
1.读入景点信息文件:
在这里插入图片描述
2.查找:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 8
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
学生信息管理系统是一种用于管理学生信息的软件系统。它能够帮助学校或教育机构高效地管理和维护学生的基本信息、课程成绩、考勤记录等重要数据。 在C语言课程设计中,学生信息管理系统可以通过使用C语言进行编程实现。首先,我们需要定义学生信息的数据结构,包括学号、姓名、年龄、性别、班级等字段。 其次,通过使用C语言中的文件操作函数,我们可以创建一个文件来存储学生信息。可以使用C语言中的文件打开、写入、读取等函数来实现将学生信息保存至文件,以及从文件中读取学生信息的功能。 在学生信息管理系统中,还可以实现添加学生、删除学生、修改学生信息等功能。通过用户输入相应的指令或菜单,我们可以在系统中进行这些操作,并将修改后的学生信息保存至文件。 此外,在管理系统中还可以实现查询学生信息、统计学生人数等功能。用户可以输入学生的学号或姓名来查询学生的相关信息,例如成绩、年龄等。通过编程实现统计学生人数的功能,可以对学生总人数、男女生人数等进行统计,并将结果输出给用户。 学生信息管理系统的设计还可以考虑使用界面来提升用户体验。在C语言中,可以使用图形界面库或控制台UI库来设计一个简洁美观的界面,使用户可以方便地进行操作。 总之,C语言课程设计中的学生信息管理系统可以利用C语言的特点和文件操作等功能,实现学生信息的添加、删除、修改、查询和统计等基本操作,提高学生信息的管理效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值