/************************************************************
版权所有(C)2017,LinZhiwen
*
* 文件名称:map.h
* 文件标识:无
*内容摘要: 存放函数的声明,结构体的声明
*其它说明: 无
*当前版本: V1.0
*作者: 林志文
*完成日期: 20170101
*
*修改记录: 0
*修改日期: 20170101
*版本号: V1.0
*修改人: 林志文
*修改内容: 创建
**********************************************************/
#ifndef _MAP_
#define _MAP_
#include <iostream>
#include <windows.h>
#include <conio.h>
#include "string"
using namespace std;
#define MAXV 16
#define LIMITLESS 9999
typedef struct
{
string cityname;
string introduction;
}VerTexType;//顶点的结构体类型
typedef struct
{
float dis;
string rode;
}Edges;
typedef struct//邻接矩阵
{
int n,e; //顶点数,边数
Edges edges[MAXV*(MAXV+1)/2];//压缩存储
VerTexType vexs[MAXV];
}MGraph;
void read(MGraph * g);
void CreateMGraph2(MGraph *G);
void Ppath(int path[],int i,int v,MGraph g);
void Dispath(float dist[],int path[],int s[],MGraph g, int v,int m);
void Dijkstra(MGraph g,int v,int m);
int CityNameTransition(string a,MGraph g);
void RouteQuery(MGraph g);
void Find(MGraph g);
void Find2(MGraph g);
void Find3(MGraph g);
void Menu(MGraph g);
#endif
/************************************************************
版权所有(C)2017,LinZhiwen
*
* 文件名称:map.cpp
* 文件标识:无
*内容摘要: 存放函数的定义
*其它说明: 无
*当前版本: V1.0
*作者: 林志文
*完成日期: 20170101
*
*修改记录: 0
*修改日期: 20170101
*版本号: V1.0
*修改人: 林志文
*修改内容: 创建
**********************************************************/
#include "map.h"
int z;
/*********************************************************
*功能描述:初始化地图
*输入参数:图的地址
*输出参数:图的地址
*返回值: 无
*其它说明:无
************************************************************/
void CreateMGraph2(MGraph *G)
{
int i=0,j=0,a=0;
G->n=16;
G->e=27;
for(i=0;i<136;i++)
{
G->edges[i].dis=0;
}
G->edges[1].dis=65.8;
G->edges[4].dis=261.4;
G->edges[8].dis=141.5;
G->edges[13].dis=147.2;
G->edges[19].dis=93.7;
G->edges[26].dis=156.9;
G->edges[34].dis=117;
G->edges[43].dis=167.2;
G->edges[53].dis=146;
G->edges[64].dis=200;
G->edges[76].dis=62.9;
G->edges[78].dis=246.4;
G->edges[79].dis=318.4;
G->edges[80].dis=164.5;
G->edges[81].dis=164.4;
G->edges[82].dis=248;
G->edges[83].dis=337.5;
G->edges[89].dis=103.8;
G->edges[100].dis=213;
G->edges[101].dis=71;
G->edges[103].dis=103.7;
G->edges[112].dis=240;
G->edges[113].dis=121.8;
G->edges[118].dis=114.5;
G->edges[125].dis=186.9;
G->edges[126].dis=140;
G->edges[131].dis=245.3;
G->edges[134].dis=67.9;
G->edges[1].rode="荣乌高速";
G->edges[4].rode="威青高速";
G->edges[8].rode="青兰高速";
G->edges[13].rode="日兰高速";
G->edges[19].rode="岗曹高速";
G->edges[26].rode="京台高速";
G->edges[34].rode="日兰高速";
G->edges[43].rode="菏东高速";
G->edges[53].rode="德上高速";
G->edges[64].rode="德滨高速";
G->edges[76].rode="滨东高速";
G->edges[78].rode="荣潍高速";
G->edges[79].rode="沈海高速";
G->edges[80].rode="潍青高速";
G->edges[81].rode="206国道";
G->edges[82].rode="长深高速";
G->edges[83].rode="潍枣高速";
G->edges[89].rode="320省道";
G->edges[100].rode="德淄高速";
G->edges[101].rode="滨淄高速";
G->edges[103].rode="青银高速";
G->edges[112].rode="济广高速";
G->edges[113].rode="济聊高速";
G->edges[118].rode="济淄高速";
G->edges[125].rode="泰枣高速";
G->edges[126].rode="日兰高速";
G->edges[131].rode="潍泰高速";
G->edges[134].rode="济泰高速";
for(i=1;i<G->n;i++)
{
a++;
for(j=0;j<a;j++)
{
if(i>=j)
{
if(G->edges[i*(i+1)/2+j].dis==0)
{
G->edges[i*(i+1)/2+j].dis=LIMITLESS;
}
}
else
{
if(G->edges[j*(j+1)/2+i].dis==0)
{
G->edges[j*(j+1)/2+i].dis=LIMITLESS;
}
}
}
}
G->vexs[0].cityname="烟台";
G->vexs[1].cityname="威海";
G->vexs[2].cityname="青岛";
G->vexs[3].cityname="日照";
G->vexs[4].cityname="临沂";
G->vexs[5].cityname="枣庄";
G->vexs[6].cityname="济宁";
G->vexs[7].cityname="菏泽";
G->vexs[8].cityname="聊城";
G->vexs[9].cityname="德州";
G->vexs[10].cityname="滨州";
G->vexs[11].cityname="东营";
G->vexs[12].cityname="潍坊";
G->vexs[13].cityname="淄博";
G->vexs[14].cityname="济南";
G->vexs[15].cityname="泰安";
/*
G->vexs[0].introduction="烟台_烟台苹果_莱阳梨";
G->vexs[1].introduction="威海_胶东大花生_荣成黄桃_乳山阳黎";
G->vexs[2].introduction="青岛_崂山_张三丰_李白_康有为_青岛啤酒";
G->vexs[3].introduction="日照_万平口_五莲山_九仙山";
G->vexs[4].introduction="临沂_沂蒙山_煎饼_凤凰城";
G->vexs[5].introduction="枣庄_台儿庄_羊肉汤";
G->vexs[6].introduction="济宁_孔子_孟子_运河之都";
G->vexs[7].introduction="菏泽_牡丹_孙膑_庄周_宋江";
G->vexs[8].introduction="聊城_东昌湖_光岳楼";
G->vexs[9].introduction="德州_太阳谷_海岛金山寺";
G->vexs[10].introduction="滨州_孙子兵法_沾化冬枣";
G->vexs[11].introduction="东营_天鹅湖_黄河入海口_石油";
G->vexs[12].introduction="潍坊_风筝_萝卜_贾思勰_孔融";
G->vexs[13].introduction="淄博_周村烧饼_齐威王_齐桓公";
G->vexs[14].introduction="济南_趵突泉_大明湖_扁鹊_芙蓉街";
G->vexs[15].introduction="泰安_泰山_鲍叔牙_左丘明_肥城桃";*/
read(G);
}
/*********************************************************
*功能描述:输出路径中间城市名(狄克斯特拉算法)
*输入参数:状态数组 当前的点 起点 图
*输出参数:状态数组 当前的点 起点 图
*返回值: 无
*其它说明:递归调用
************************************************************/
void Ppath(int path[],int i,int v,MGraph g)
{
int k,a;
k=path[i];
if(k==v)
return;
Ppath(path,k,v,g);
if(z>=k)
{
a=z*(z+1)/2+k;
cout<<"--"<<g.edges[a].rode<<"--";
z=k;
}
else
{
a=k*(k+1)/2+z;
cout<<"--"<<g.edges[a].rode<<"--";
z=k;
}
cout<<g.vexs[k].cityname;
}
/*********************************************************
*功能描述:输出起点和终点城市名(狄克斯特拉算法)
*输入参数:状态数组 状态数组 状态数组 图 起点 终点
*输出参数:状态数组 当前的点 起点 图
*返回值: 无
*其它说明:无
************************************************************/
void Dispath(float dist[],int path[],int s[],MGraph g, int v,int m)
{
int i,a;
z=v;
for(i=0;i<g.n;i++)
{
if(s[i]==1)
{
if(i==m)
{
cout<<"从"<<g.vexs[v].cityname<<"到"<<g.vexs[i].cityname<<"的最短路程为:"<<dist[i]<<"公里"<<" "<<"路线为:"<<g.vexs[v].cityname;
if(path[i]==v)//如果两个两个城市相邻
{
if(v>=i)
{
a=v*(v+1)/2+i;
cout<<"--"<<g.edges[a].rode<<"--";
}
else
{
a=i*(i+1)/2+v;
cout<<"--"<<g.edges[a].rode<<"--";
}
cout<<g.vexs[i].cityname<<endl;
return;
}
Ppath(path,i,v,g);//中间城市
if(z>=i)//输出倒数第二个城市和终点城市
{
a=z*(z+1)/2+i;
cout<<"--"<<g.edges[a].rode<<"--";
}
else
{
a=i*(i+1)/2+z;
cout<<"--"<<g.edges[a].rode<<"--";
}
cout<<g.vexs[i].cityname<<endl;
}
}
else
cout<<"不存在路径"<<"从"<<v<<"到"<<i;
}
}
/
/*********************************************************
*功能描述: 狄克斯特拉算法,从一个点到其他所有点的最短路径, 修改为输入两点,求其最短路径。
*输入参数: 图 起点 终点
*输出参数: 状态数组 状态数组 状态数组 图 起点 终点
*返回值: 无
*其它说明: 无
************************************************************/
void Dijkstra(MGraph g,int v,int m)
{
float mindis;
int i,j,u,a;
int s[MAXV];
float dist[MAXV];
int path[MAXV];
/定义辅助存储和初值设置
for(i=0;i<g.n;i++)
{
s[i]=0;
if(v>=i)
{
a=v*(v+1)/2+i;
}
else
{
a=i*(i+1)/2+v;
}
dist[i]=g.edges[a].dis;
if(g.edges[a].dis<LIMITLESS)
{
path[i]=v;
}
else
{
path[i]=-1;
}
}
s[v]=1;
path[v]=0;
/
选取不在S中且具有最小距离的顶点U
for(i=0;i<g.n;i++)
{
mindis=LIMITLESS;
for(j=0;j<g.n;j++)
{
if(s[j]==0&&dist[j]<mindis)
{
u=j;
mindis=dist[j];
}
}
s[u]=1;//找到后顶点u加入S中
for(j=0;j<g.n;j++) //修改不在S中的顶点的距离
{
if(s[j]==0)
{
if(u>=j)
{
a=u*(u+1)/2+j;
}
else
{
a=j*(j+1)/2+u;
}
if(g.edges[a].dis<LIMITLESS&&dist[u]+g.edges[a].dis<dist[j])
{
dist[j]=dist[u]+g.edges[a].dis;
path[j]=u;
}
}
}
}
Dispath(dist,path,s,g,v,m);//输出最短路路径
}
/*********************************************************
*功能描述: 输入的城市名称转为顶点编号
*输入参数: 城市名 图
*输出参数: 无
*返回值: 输入正确返回顶点编号,错误返回-1。
*其它说明: 无
************************************************************/
int CityNameTransition(string a,MGraph g)
{
int i=0,t=0;
for(i=0;i<g.n;i++)
{
if(g.vexs[i].cityname==a)
{
return i;
}
}
return -1;
}
/*********************************************************
*功能描述: 路线查询函数, 输入出发地和目的地城市名,输出最短路线和路程。
*输入参数: 图
*输出参数: 城市名
*返回值: 输入正确返回顶点编号,错误返回-1。
*其它说明: 无
************************************************************/
void RouteQuery(MGraph g)
{
string city1;
string city2;
int a,b;
cout<<"请输入出发地城市名: ";
cin>>city1;
cout<<endl;
a=CityNameTransition(city1,g);
if(a==-1)
{
cout<<"无该城市"<<endl;
return;
}
else
{
cout<<"请输入目的地城市名: ";
cin>>city2;
cout<<endl;
b=CityNameTransition(city2,g);
if(b==-1)
{
cout<<"无该城市"<<endl;
return;
}
else
{
Dijkstra(g,a,b );
}
}
}
/*********************************************************
*功能描述: 旅游景点查询函数,输入要查询的旅游景点,输出该景点所在地。
*输入参数: 图
*输出参数: 无
*返回值: 无
*其它说明: 无
************************************************************/
void Find(MGraph g)
{
string str1;
int i;
cout<<"请输入您要查找的旅游景点: ";
cin>>str1;
for(i=0;i<g.n;i++)
{
string::size_type idx=g.vexs[i].introduction.find(str1);
if(idx!=string::npos)
{
cout<<"你所查询的"<<str1<<"在 "<<g.vexs[i].cityname<<endl;
return;
}
}
cout<<"没有查询到"<<str1<<endl;
}
/*********************************************************
*功能描述: 美食特产查询函数,输入要查询的美食特产,输出该美食特产所在地。
*输入参数: 图
*输出参数: 无
*返回值: 无
*其它说明: 无
************************************************************/
void Find2(MGraph g)
{
string str1;
int i;
cout<<"请输入您要查找的特产美食: ";
cin>>str1;
for(i=0;i<g.n;i++)
{
string::size_type idx=g.vexs[i].introduction.find(str1);
if(idx!=string::npos)
{
cout<<"你所查询的"<<str1<<"在"<<g.vexs[i].cityname<<endl;
return;
}
}
cout<<"没有查询到"<<str1<<endl;
}
/*********************************************************
*功能描述: 历史名人查询函数,输入要查询的历史名人,输出该历史名人所在地。
*输入参数: 图
*输出参数: 无
*返回值: 无
*其它说明: 无
************************************************************/
void Find3(MGraph g)
{
string str1;
int i;
cout<<"请输入您要查找的历史名人: ";
cin>>str1;
for(i=0;i<g.n;i++)
{
string::size_type idx=g.vexs[i].introduction.find(str1);
if(idx!=string::npos)
{
cout<<"你所查询的"<<str1<<"的故乡在 "<<g.vexs[i].cityname<<endl;
return;
}
}
cout<<"没有查询到"<<str1<<"的故乡"<<endl;
}
/*********************************************************
*功能描述: 菜单函数,输入选项,调用相应函数,
*输入参数: 图
*输出参数: 无
*返回值: 无
*其它说明: 递归调用。
************************************************************/
void Menu(MGraph g)
{
int option;
printf("--------请选择相应功能------------\n\n");
printf(" 1 路线查询|\n");
printf(" 2 旅游景点查询|\n");
printf(" 3 美食小吃查询|\n");
printf(" 4 历史文化名人查询|\n");
printf(" 5 退出|\n");
cin>>option;
switch(option)
{
case 1:
system("cls");
RouteQuery(g);
getch();
break;
case 2:
system("cls");
Find(g);
getch();
break;
case 3:
system("cls");
Find2(g);
getch();
break;
case 4:
system("cls");
Find3(g);
getch();
break;
case 5:
goto aa;
system("cls");
getch();
break;
default:
break;
}
Menu(g);
aa:;
}
/*********************************************************
*功能描述: 读取TXT文件函数,初始化城市简介。
*输入参数: 图的地址
*输出参数: 无
*返回值: 无
*其它说明: 无
************************************************************/
void read(MGraph *g)//从文件中读取信息
{
int i=0;
FILE *fp;
fp=fopen("c://lin.txt.txt","r");//以可读方式打开lin.txt文件
if(!fp)
{
printf("文件不存在\n");
return;
}
char a[100];//临时的字符数组,用来装TXT中的字符串
string a1;
while(fscanf(fp,"%s\n",a)>0&&i<16)//
{
string a1 (a);//将字符数组转化为string类型。
g->vexs[i].introduction=a1;
i++;
}
fclose(fp);//关闭文件
}
/************************************************************
版权所有(C)2017,LinZhiwen
*
* 文件名称:main.cpp
* 文件标识:无
*内容摘要: 主函数
*其它说明: 无
*当前版本: V1.0
*作者: 林志文
*完成日期: 20170101
*
*修改记录: 0
*修改日期: 20170101
*版本号: V1.0
*修改人: 林志文
*修改内容: 创建
**********************************************************/
#include "map.h"
int main()
{
MGraph *g;
g= new MGraph;
CreateMGraph2(g);
Menu(*g);
return 0;
}