/***********************************************************
* 版权所有 (C)2017,sunrenyuan
*
* 文件名称: main.cpp
* 文件标识:main
* 内容摘要:函数文件
* 其它说明:主函数
* 当前版本: V3.0
* 作 者:孙仁圆
* 完成日期: 2017.12.21
*
* 修改记录1:
* 修改日期 :2017.12.18
* 版本号: V1.0
* 修改人: 孙仁圆
* 修改内容:创建
*
* 修改记录2:
* 修改日期 :2017.12.20
* 版本号: V2.0
* 修改人: 孙仁圆
* 修改内容:增加了Djp算法
*
* 修改记录3:
* 修改日期:2017.12.21
* 版本号: V3.0
* 修改人: 孙仁圆
* 修改内容:完善了增加景点函数的漏洞
*
**********************************************************/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "jiemi.h"
using namespace std;
int main()
{
int vnum;
int i;
int path[MaxViewNum][MaxViewNum]; /*定义存贮路径*/
int shortest[MaxViewNum][MaxViewNum];
MGraph sq;
init(sq,shortest);
char k;
system("color 3B");
printf(" **************************************************************************\n");
printf("* *\n");
printf("* *\n");
printf("* 欢迎来到烟台大学 *\n");
printf("* *\n");
printf("* *\n");
printf(" **************************************************************************\n");
printf("\n");
while(1)
{
printf("1.景点信息查询请按“1”键;\n");
printf("2.景点最短路径查询(佛洛依德算法)请按“2”键;\n");
printf("3.景点最短路径查询(迪杰斯特拉算法)请按“3”键;\n");
printf("4.校内景点地图查询请按“4”键;\n");
printf("5.退出系统请按“5”键;\n");
cout<<"6.增加景点请按“6“键;"<<endl;
cout<<"7.景点附加道路请按“7“键;"<<endl;
cout<<"8.修改景点信息请按“8”键;"<<endl;
printf("请选择: \n");
scanf("%c",&k);
fflush(stdin);
switch(k)
{
case '1':printf("景点介绍查询。\n");
introduce(sq); break;
case '2':printf("");
Floyd(sq); break;
case '3':printf("景点最短路径查询。");
Djp(vnum,sq) ; break;
case '4':printf("景点地图。\n");
map(); break;
case '5':printf("谢谢使用!\n");
case '6': printf("增加\n");
addviews(sq);
break;
case '8': printf("修改\n");
change(sq); fflush(stdin);
break;
case '7':printf("请输入你要查询的边\n");
cin>>i;
addlen2(sq,i) ; break;
case 9:
deletelen(sq);
break;
exit(0);
}
}
system("pause");
return 0;
}
/*********************************************************
* 版权所有 (C)2017,sunrenyuan
*
* 文件名称:jiemi.cpp
* 文件标识:jiemi.cpp
* 内容摘要:各种函数库
* 其它说明:
* 当前版本: V3.0
* 作 者: 孙仁圆
* 完成日期: 2017.12.21
*
************************************************************/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include "jiemi.h"
using namespace std;
/*********************************************************
* 功能描述:前向递归查找路径上的顶点
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Dijkstra算法库
************************************************************/
void init(MGraph &MGr,int shortest[MaxViewNum][MaxViewNum])
{
MGr.view[1].num=1;
strcpy(MGr.view[1].date.name,"学校南门");
strcpy(MGr.view[1].date.number,"001");
strcpy(MGr.view[1].date.introduce,"坐落于银海路,对面为世纪华府,市井繁华,交通便利。");
MGr.view[2].num=2;
strcpy(MGr.view[2].date.name,"新图书馆");
strcpy(MGr.view[2].date.number,"002");
strcpy(MGr.view[2].date.introduce,"借阅图书的地方,也可以让师生自习");
MGr.view[3].num=3;
strcpy(MGr.view[3].date.name,"综合楼");
strcpy(MGr.view[3].date.number,"003");
strcpy(MGr.view[3].date.introduce,"各大专业学院讲课的地方");
MGr.view[4].num=4;
strcpy(MGr.view[4].date.name,"七餐");
strcpy(MGr.view[4].date.number,"004");
strcpy(MGr.view[4].date.introduce,"据说是亚洲综合性餐厅");
MGr.view[5].num=5;
strcpy(MGr.view[5].date.name,"西门");
strcpy(MGr.view[5].date.number,"005");
strcpy(MGr.view[5].date.introduce,"位于清泉路");
MGr.view[6].num=6;
strcpy(MGr.view[6].date.name,"一教二教三教");
strcpy(MGr.view[6].date.number,"006");
strcpy(MGr.view[6].date.introduce,"考研天堂。");
MGr.view[7].num=7;
strcpy(MGr.view[7].date.name,"三元湖");
strcpy(MGr.view[7].date.number,"007");
strcpy(MGr.view[7].date.introduce,"风景优美");
MGr.view[8].num=8;
strcpy(MGr.view[8].date.name,"钟楼");
strcpy(MGr.view[8].date.number,"008");
strcpy(MGr.view[8].date.introduce,"又名科技馆,是计控学院的大本营");
MGr.view[9].num=9;
strcpy(MGr.view[9].date.name,"一餐二餐三餐");
strcpy(MGr.view[9].date.number,"009");
strcpy(MGr.view[9].date.introduce,"一般在北校的在这吃。");
MGr.view[10].num=10;
strcpy(MGr.view[10].date.name,"家属楼");
strcpy(MGr.view[10].date.number,"010");
strcpy(MGr.view[10].date.introduce,"老师们居住的地方。");
MGr.view[11].num=11;
strcpy(MGr.view[11].date.name,"烟大北门");
strcpy(MGr.view[11].date.number,"011");
strcpy(MGr.view[11].date.introduce,"位于清泉路,对面是新世界百货。");
MGr.view[12].num=12;
strcpy(MGr.view[12].date.name,"烟大东门");
strcpy(MGr.view[12].date.number,"012");
strcpy(MGr.view[12].date.introduce,"位于滨海中路,出门就可以看到海景。");
MGr.v=12;
int i,j;
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
MGr.length[i][j]=MaxRoad;
}
}
for(i=1;i<=N;i++)
{
shortest[i][j]=0;
}
MGr.length[1][2]=MGr.length[2][1]=40;
MGr.length[1][3]=MGr.length[3][1]=40;
MGr.length[2][3]=MGr.length[3][2]=10;
MGr.length[2][5]=MGr.length[5][2]=60;
MGr.length[3][4]=MGr.length[4][3]=60;
MGr.length[3][5]=MGr.length[5][3]=100;
MGr.length[5][6]=MGr.length[6][5]=10;
MGr.length[6][7]=MGr.length[7][6]=10;
MGr.length[6][9]=MGr.length[9][6]=10;
MGr.length[7][8]=MGr.length[8][7]=10;
MGr.length[8][9]=MGr.length[9][8]=20;
MGr.length[8][10]=MGr.length[10][8]=40;
MGr.length[9][10]=MGr.length[10][9]=20;
MGr.length[9][11]=MGr.length[11][9]=30;
MGr.length[10][11]=MGr.length[11][10]=10;
MGr.length[11][12]=MGr.length[12][11]=100;
MGr.length[10][12]=MGr.length[12][10]=90;
MGr.e=17;
MGr.length[1][1]=MGr.length[2][2]=MGr.length[3][3]=MGr.length[4][4]=0;
MGr.length[5][5]=MGr.length[6][6]=MGr.length[7][7]=MGr.length[8][8]=0;
MGr.length[9][9]=MGr.length[10][10]=MGr.length[11][11]=MGr.length[12][12]=0;
}
/*********************************************************
* 功能描述:景点介绍
* 输入参数:所需查询的景点编号
* 输出参数:无
* 返回值 :无
* 其它说明:数组从一开始存储
************************************************************/
void introduce(MGraph &MGr)
{
int m;
int i;
printf("请输入查询景点编号:\n");
scanf("%d",&m);
fflush(stdin);//清除缓存,清楚界面
for(i=1;i<=MGr.v;i++)
{
if(i==m)
{
printf("景点代号:%s\t",MGr.view[i].date.number);
printf("景点名称:%s\n",MGr.view[i].date.name);
printf("景点简介:%s\n",MGr.view[i].date.introduce);
break;
}
}
}
/*********************************************************
* 功能描述:地图界面
* 输入参数:无
* 输出参数:相应的操作
* 返回值 :无
* 其它说明:帮助页面
************************************************************/
void map()
{
system("color 3B");
printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("┃┏━━━━━━━━┓┏━━━━━┓ ┏━━━━━━━┓ ┃\n");
printf("┃┃11.北门 ┃┃10.家属院 ┃ ┃ 12. 东门┃ ┃\n");
printf("┃┗━━━━━━━━┛┗━━━━━┛ ┗━━━━━━━┛ ┃\n");
printf("┃ ┃\n");
printf("┃ ┏━━━━━━┓ ┃\n");
printf("┃ ┃ 9 . ┃ ┏━━━━┓ ┃\n");
printf("┃ ┃一餐二餐三餐┃ ┃8.钟楼 ┃ ┃\n");
printf("┃ ┗━━━━━━┛ ┗━━━━┛ ┃\n");
printf("┃┏━━━━━━━━━━━━━━┓ ┏━━━━┓ ┃\n");
printf("┃┃ 6 . 一教二教三教 ┃ ┃7.三元湖┃ ┏━━━━━━┓ ┃\n");
printf("┃┗━━━━━━━━━━━━━━┛ ┗━━━━┛ ┃ 4. ┃ ┃\n");
printf("┃┏━━━━┓ ┃ 七餐 ┃ ┃\n");
printf("┃┃5 .西门 ┃ ┃ ┃ ┃\n");
printf("┃┗━━━━┛ ┃ ┃ ┃\n");
printf("┃ ┗━━━━━━┛ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┏━━━━━━━━━┓ ┃\n");
printf("┃ ┃ ┃ ┃\n");
printf("┃ ┃ 2.图 ┃ ┃\n");
printf("┃ ┃ 书 ┃ ┏━━━━━━┓ ┃\n");
printf("┃ ┃ 馆 ┃ ┃ 综 ┃ ┃\n");
printf("┃ ┃ ┃ ┃ 3. 合 ┃ ┃\n");
printf("┃ ┃ ┃ ┃ 楼 ┃ ┃\n");
printf("┃ ┗━━━━━━━━━┛ ┗━━━━━━┛ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┏━━━━━┓ ┃\n");
printf("┃ ┃1.学校南门┃ ┃\n");
printf("┃ ┗━━━━━┛ ┃\n");
printf("┃ ┃\n");
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
}
/*********************************************************
* 功能描述:前向递归查找路径上的顶点
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Floyd算法库
************************************************************/
void Ppath(int path[][MaxViewNum],int i,int j) //前向递归查找路径上的顶点
{
int k;
k=path[i][j];
if (k==-1) return; //找到了起点则返回
Ppath(path,i,k); //找顶点i的前一个顶点k
printf("%d,",k);
Ppath(path,k,j); //找顶点k的前一个顶点j
}
/*********************************************************
* 功能描述:输出最短路径
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Floyd算法库
************************************************************/
void Dispath(int A[][MaxViewNum],int path[][MaxViewNum],int v)
{
int i,j;
for (i=1; i<=v; i++)
for (j=1; j<=v; j++)
{
if (A[i][j]==Infinite)
{
if (i!=j)
printf("从%d到%d没有路径\n",i,j);
}
else
{
printf(" 从%d到%d=>路径长度:%d 路径:",i,j,A[i][j]);
printf("%d,",i); //输出路径上的起点
Ppath(path,i,j); //输出路径上的中间点
printf("%d\n",j); //输出路径上的终点
}
}
}
/*********************************************************
* 功能描述:输出最短路径
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Floyd算法库
************************************************************/
void Floyd(MGraph MGr)
{
int A[MaxViewNum][MaxViewNum],path[MaxViewNum][MaxViewNum];
int i,j,k;
for (i=1; i<=MGr.v; i++)
for (j=1; j<=MGr.v; j++)
{
A[i][j]=MGr.length[i][j];
path[i][j]=-1;
}
for (k=1; k<=MGr.v; k++)//k为中间点
{
for (i=1; i<=MGr.v; i++)//起点
for (j=1; j<=MGr.v; j++)//终点
if (A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
Dispath(A,path,MGr.v); //输出最短路径
}
/*********************************************************
* 功能描述:添加景点,添加道路
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明: 主要实现在另一个
************************************************************/
void addviews(MGraph &MGr)//添加景点,添加道路
{
printf("请输入需要添加的将要建设的景点:\n");
printf("请输入景点编号:");
addviewsq(MGr) ;
}
/*********************************************************
* 功能描述:增加顶点,增加道路
* 输入参数:需要查询的顶点
* 输出参数:顶点信息
* 返回值 :无
* 其它说明:主要实现
************************************************************/
void addviewsq(MGraph &MGr)
{int i;
int a;//你输入的景点编号
char b;//做输入判断
cout<<"请输入你要查询的景点编号"<<endl;
cin>>a;
if(a<=MGr.v)
{
fflush(stdin);//清屏
cout<<"此节点已经在是否重新输入"<<endl;
scanf("%c",&b);
if(b=='y')
{
addviewsq(MGr);
}
fflush(stdin);
if(b=='n')
{
//main();
return ;
}
}
else
{
MGr.v++;
printf("请输入景点名称:\n");
scanf("%s",MGr.view[MGr.v].date.name);
printf("请输入景点代号:\n");
scanf("%s",MGr.view[MGr.v].date.number);
printf("请输入景点信息:\n");
scanf("%s",MGr.view[MGr.v].date.introduce);
printf("添加完毕\n");
for(i=1;i<=MGr.v;i++)
{
MGr.length[MGr.v][i]=MGr.length[i][MGr.v]=Infinite;
}
}
fflush(stdin);//清屏
}
/*********************************************************
* 功能描述:前向递归查找路径上的顶点
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Dijkstra算法库
************************************************************/
void Ppath1(int path[],int i,int vs) //前向递归查找路径上的顶点
{
int k;
k=path[i];
if (k==vs) return; //找到了起点则返回
Ppath1(path,k,vs); //找顶点k的前一个顶点
printf("%d->",k); //输出顶点k
}
/*********************************************************
* 功能描述:输出最短路径
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Dijkstra算法库
************************************************************/
void Dispath1(int dist[],int path[],int s[],int v,int vs)//vs输入的顶点号
{
int i;
for (i=1;i<=v;i++)
if (s[i]==1)
{
printf(" 从%d到%d的最短路径长度为:%d\t路径为:",vs,i,dist[i]);
if(i==vs)
{
printf("%d->%d\n",vs,i);
}
else
{
printf("%d->",vs); //输出路径上的起点
Ppath1(path,i,vs); //输出路径上的中间点
printf("%d\n",i); //输出路径上的终点
}
}
else
printf("从%d到%d不存在路径\n",vs,i);
}
/*********************************************************
* 功能描述:输出最短路径
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Dijkstra算法库
************************************************************/
void Djst1(MGraph MGr,int vs)
{
int dist[MaxViewNum],path[MaxViewNum];
int s[MaxViewNum];
int mindis,i,j,u;
for (i=1; i<=MGr.v; i++)
{
dist[i]=MGr.length[vs][i]; //距离初始化
s[i]=0; //s[]置空
if (MGr.length[vs][i]<Infinite) //路径初始化
path[i]=vs;
else
path[i]=-1;
}
s[vs]=1;
path[vs]=0; //源点编号v放入s中
for (i=1; i<=MGr.v; i++) //循环直到所有顶点的最短路径都求出
{
mindis=Infinite; //mindis置最小长度初值
for (j=1; j<=MGr.v; j++) //选取不在s中且具有最小距离的顶点u
if (s[j]==0 && dist[j]<mindis)
{
u=j;
mindis=dist[j];
}
s[u]=1; //顶点u加入s中
for (j=1; j<=MGr.v; j++) //修改不在s中的顶点的距离
if (s[j]==0)
if (MGr.length[u][j]<Infinite && dist[u]+MGr.length[u][j]<dist[j])
{
dist[j]=dist[u]+MGr.length[u][j];
path[j]=u;
}
}
Dispath1(dist,path,s,MGr.v,vs); //输出最短路径
}
/*********************************************************
* 功能描述:输出最短路径
* 输入参数:无
* 输出参数:无
* 返回值 :无
* 其它说明:Dijkstra算法库
************************************************************/
void Djp(int vnum,MGraph &MGr)
{
char a;
while(1)
{
printf("请输入你要查寻最短路径的起始点:");
scanf("%d",&vnum);
fflush(stdin);
if(vnum>=MGr.v || vnum<=0)
{
printf("无此节点请重新输入!");
printf("是否重新输入?请输入y or n\n");
scanf("%c",&a);
if(a=='y')
{
printf("请输入你要查寻最短路径的起始点:");
scanf("%d",&vnum);
Djp(vnum,MGr);
}
if(a=='n')
{
fflush(stdin);
//main();
break;
}
}
else
{
fflush(stdin);
Djst1(MGr,vnum);
break;
}
}
}
/*********************************************************
* 功能描述:修改景点信息
* 输入参数:景点名称
* 输出参数:无
* 返回值 :无
* 其它说明:无
************************************************************/
void change(MGraph &MGr)
{
int a;
printf("请输入你要更改的信息的代号:");
scanf("%d",&a);
if(a<=MGr.v-1)
{
printf("请输入修改的景点名:\n");
scanf("%s",MGr.view[a].date.name);
printf("请输入修改的景点代号:\n");
scanf("%s",MGr.view[a].date.number);
printf("请输入修改的景点信息:\n");
scanf("%s",MGr.view[a].date.introduce);
}
if(a>=MGr.v || a<0)
{
printf("此节点不存在!\n");
}
}
/*********************************************************
* 功能描述:增加景点道路
* 输入参数:景点名称
* 输出参数:无
* 返回值 :无
* 其它说明:无
************************************************************/
void addlen2(MGraph &MGr,int i)
{
int j;
int d;
printf("请输入你要添加的终点编号:\n");
scanf("%d",&j);
if(j>MGr.v)
{
printf("此节点不存在或者是本身!请重新输入!");
addlen2(MGr,i);
}
else
{
printf("请输入距离:\n");
scanf("%d",&d);
MGr.length[i][j]=MGr.length[j][i]=d;
}
fflush(stdin);
}
/*********************************************************
* 功能描述:删除景点道路
* 输入参数:两个景点
* 输出参数:无
* 返回值 :无
* 其它说明:无
************************************************************/
void deletelen(MGraph &MGr)
{
int i,j;
printf("请输入你要删除的路径端点(删除后均连通):\n");
printf("请输入起点:\n");
scanf("%d",&i);
printf("请输入终点:\n");
scanf("%d",&j);
if(MGr.length[i][j]!=Infinite)
{
if(i==j)
{
MGr.length[i][j]=MGr.length[j][i]=0;
printf("输入不合理!\n");
}
else
{
MGr.length[i][j]=MGr.length[j][i]=Infinite;
MGr.e--;
printf("删除路径成功!\n");
}
}
else
{
printf("无直接路径\n");
}
}
/*********************************************************
* 版权所有 (C)2017,sunrenyuan
*
* 文件名称:jiemi.h
* 文件标识:jiemi.h
* 内容摘要:各种函数库定义
* 其它说明:
* 当前版本: V3.0
* 作 者: 孙仁圆
* 完成日期: 2017.12.21
*
************************************************************/
#ifndef JIEMI_H_INCLUDED
#define JIEMI_H_INCLUDED
#endif // JIEMI_H_INCLUDED
#define MaxSize 100
#define NOTVISITED 0
#define Infinite 1073741823
#define MaxViewNum 50 /*景点个数最大50*/
#define MaxRoad 1000 /*定义路径为无穷大*/
#define N 12 /*目前景点个数*/
typedef struct
{
char name[30]; //景点名称
char number[10]; //代号
char introduce[200]; //景点介绍
}Elemtype; //景点信息
typedef struct
{
int num; //景点编号
Elemtype date;// 景点信息
}View;
typedef struct
{
View view[MaxViewNum];//存放景点的一位数组 数组0 单元没有用上
int v,e;//定点数边数
int length[MaxViewNum][MaxViewNum];//存放路径长度
}MGraph;
void addviewsq(MGraph &MGr);//增加顶点
void init(MGraph &MGr,int shortest[MaxViewNum][MaxViewNum]);//景点建设
void introduce(MGraph &MGr);//景点介绍
void map();//景点地图
void Floyd(MGraph MGr);//Floyd算法
void Ppath(int path[][MaxViewNum],int i,int j) ;//递归查找顶点
void Dispath(int A[][MaxViewNum],int path[][MaxViewNum],int v);
void addviews(MGraph &MGr);//增加顶点
void Djst1(MGraph MGr,int vs);//Dijkstra算法
void Dispath1(int dist[],int path[],int s[],int v,int vs);//
void Ppath1(int path[],int i,int vs) ;//前向递归查找路径上的顶点
void Djp(int vnum,MGraph &MGr);//
void change(MGraph &MGr);//修改景点信息
void addlen2(MGraph &MGr,int i);//增加边
void deletelen(MGraph &MGr);//删除边
![](https://img-blog.csdn.net/20171221135731733?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVueXVhbnN1bg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171221135737075?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVueXVhbnN1bg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171221135741224?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVueXVhbnN1bg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171221135747116?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVueXVhbnN1bg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171221135756611?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVueXVhbnN1bg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171221135801981?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVueXVhbnN1bg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)