C语言实现旅游景点咨询系统

 更新时间:2019年12月27日 14:16:46   作者:夏.谨之  
这篇文章主要为大家详细介绍了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.查找:

更多学习资料请关注专题《管理系统开发》。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

相关文章

  • C语言排序算法之冒泡排序实现方法【改进版】

    C语言排序算法之冒泡排序实现方法【改进版】

    这篇文章主要介绍了C语言排序算法之冒泡排序实现方法,结合具体实例形式分析了C语言实现的基本冒泡排序实现方法及增设flag标志位的改进型算法,需要的朋友可以参考下
    2017-09-09
  • c++ 如何合并两个有序链表

    c++ 如何合并两个有序链表

    这篇文章主要介绍了c++ 如何合并两个有序链表,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下
    2020-08-08
  • C++多态的实现及原理详细解析

    C++多态的实现及原理详细解析

    C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数
    2013-09-09
  • C语言实现简单翻译功能

    C语言实现简单翻译功能

    这篇文章主要为大家详细介绍了C语言实现简单翻译功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • C++ 关于MFC List Control 控件的总结

    C++ 关于MFC List Control 控件的总结

    这篇文章主要介绍了C++ 关于MFC List Control 控件的总结的相关资料,十分的详细,有需要的朋友可以参考下
    2015-06-06
  • 如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?

    如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?

    本篇文章是对如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方的实现方法,进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++ Boost Random随机函数详解

    C++ Boost Random随机函数详解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • 使用c语言生成随机数的示例分享

    使用c语言生成随机数的示例分享

    在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,这篇文章主要介绍了使用c语言生成随机数的示例,需要的朋友可以参考下
    2014-03-03
  • C++ Boost PointerContainer智能指针详解

    C++ Boost PointerContainer智能指针详解

    智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。虽然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷贝和赋值操作),因此很少有人使用。它是Boost各组件中,应用最为广泛的一个
    2022-11-11
  • C语言文件读写操作介绍与简单示例

    C语言文件读写操作介绍与简单示例

    这篇文章主要给大家介绍了关于C语言文件读写操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论