这是第一次写这个,看见有很多同学都在写这个利用迪杰斯特拉和佛洛依德算法写校园导航程序,就把自己写的贴出来,以供参考!自己写时也借鉴了别人的程序,见谅,就把自己这个定义为转载吧
#include <iostream>
#include<stdlib.h>#define VEXNUM 14 //顶点数
#define ARCNUM 19 //边数
#define MAX 5000
#define NUM 20
using namespace std;
typedef struct //定义顶点的类型(结构)
{
int number; // 景点编号
char *name; //景点名称
}DINGDIAN;
typedef struct //定义图的类型(结构)
{
DINGDIAN vex[VEXNUM]; //顶点的信息
int arcs[ARCNUM][ARCNUM]; //邻接矩阵
int vexnum,arcnum ; //顶点数和边数
}MGraph;
MGraph G; // 把图定义为全局变量
MGraph InitGraph(); //创建图的函数
void Changes(MGraph *G); //修改有直接路径的景点的距离
void printVex(MGraph *G); //输出每个顶点
void printArc(MGraph *G); //输出每条边
void shortsepath_Dijkstra(MGraph *G); //迪杰斯特拉算法求最短路径
void shortsepath_Floyd(MGraph *G); //弗洛伊德求最短路径
void zhupingmu(); //主界面
char menu(); // 主菜单
MGraph InitGraph() // 初始化图
{
int i,j;
G.vexnum=VEXNUM; // 初始化图中的顶点数和边数
G.arcnum=ARCNUM; // 初始化图中的边数
for(i=0;i<G.vexnum;++i)
G.vex[i].number=i; // 初始化每一个顶点的编号
G.vex[0].name="纪念碑"; // 定义景点名称
G.vex[1].name="正门";
G.vex[2].name="图书馆";
G.vex[3].name="桃花林";
G.vex[4].name="食堂";
G.vex[5].name="教学楼";
G.vex[6].name="东门";
G.vex[7].name="小西湖";
G.vex[8].name="寝室";
G.vex[9].name="西门";
G.vex[10].name="假山";
G.vex[11].name="体育馆";
G.vex[12].name="荷花池";
G.vex[13].name="北门";
for(i=0;i<G.vexnum;++i) // 初始化所有的边为MAX,表示这两个景点之间是不可到达
for(j=0;j<G.vexnum;++j)
G.arcs[i][j]=MAX;
//下边是可直接到达的景点间的距离,为无向图,所以同时赋值
G.arcs[0][1]=G.arcs[1][0]=200;
G.arcs[1][2]=G.arcs[2][1]=200;
G.arcs[1][3]=G.arcs[3][1]=450;
G.arcs[1][4]=G.arcs[4][1]=450;
G.arcs[2][5]=G.arcs[5][2]=350;
G.arcs[2][7]=G.arcs[7][2]=300;
G.arcs[2][8]=G.arcs[8][2]=400;
G.arcs[3][5]=G.arcs[5][3]=200;
G.arcs[4][8]=G.arcs[8][4]=200;
G.arcs[5][6]=G.arcs[6][5]=100;
G.arcs[5][11]=G.arcs[11][5]=200;
G.arcs[5][12]=G.arcs[12][5]=100;
G.arcs[7][11]=G.arcs[11][7]=200;
G.arcs[8][9]=G.arcs[9][8]=200;
G.arcs[8][10]=G.arcs[10][8]=100;
G.arcs[8][11]=G.arcs[11][8]=500;
G.arcs[10][11]=G.arcs[11][10]=300;
G.arcs[11][12]=G.arcs[12][11]=200;
G.arcs[11][13]=G.arcs[13][11]=100;
return G;
}
void Changes(MGraph *G) //修改有直接路径的景点的距离
{
int v0,v1,length;
cout<<"输入两点"<<endl<<"起点"<<endl;
cin>>v0;
v0=v0-1; //数组下标比实际数小1
cout<<"终点"<<endl;
cin>>v1;
v1=v1-1;
cout<<"距离:"<<endl;
cin>>length;
G->arcs[v0][v1]=G->arcs[v1][v0]=length; //为无向图的两点赋值
cout<<"修改成功! "<<G->vex[v0].name<<"与"<<G->vex[v1].name<<"的距离为: "<<length<<" 米"<<endl;
}
void printVex(MGraph *G) //输出每个顶点
{
int i;
for(i=0;i<G->vexnum;i++)
cout<<G->vex[i].number+1<<G->vex[i].name<<endl;
}
void printArc(MGraph *G) //输出每条边
{
int i,j;
for(i=0;i<G->vexnum;++i)
for(j=0;j<G->vexnum;++j)
if(G->arcs[i][j]<MAX)
{
cout<<G->vex[i].name<<"----->"<<G->vex[j].name<<" :"<<G->arcs[i][j]<<"米"<<endl;
}
}
void shortsepath_Dijkstra(MGraph *G) //迪杰斯特拉算法求最短路径
{
int v,w,i,j,min,x,v0,v1;
int S[NUM], D[NUM], path[NUM][NUM];
while(true){ //判断起点是否合法
cout<<"请输入正确起点:"<<endl;
cin>>v0;
if(v0>0 && v0<VEXNUM )
break;
}
v0=v0-1; //数组下标比实际数小1
while(true){ //判断终点是否合法
cout<<"请输入正确终点:"<<endl;
cin>>v1;
if(v1>0 && v1<VEXNUM )
break;
}
v1=v1-1;
for(v=0;v<G->vexnum;++v) //初始化
{
S[v]=0; //S初始为空集
D[v]=G->arcs[v0][v]; //将v0到各个终点的最短距离初始化为弧上的权值
for(w=0;w<G->vexnum;++w)
path[v][w]=0; //用二维数组标记路径,此时全部初始化为0
if(D[v]<MAX) //若有最短距离
{
path[v][v0]=1;path[v][v]=1; //更新此点到起点v0以及该点本身的path为1
}
} //结束时与起点v0有直接最短路径的点以及那点自身的path更新为1
D[v0]=0; //源点自身到自身距离为0
S[v0]=true; //将起点v0加入到S集合中
/*---初始化结束,开始主循环,每次求的v0到某个顶点v的最短路径,将v加到S集合中*/
for(i=1;i<G->vexnum;++i) //对其余n-1个顶点,依次进行计算
{
min=MAX; //设两点之间不能到达
for(w=0;w<G->vexnum;++w)
{
if(!S[w])
if(D[w]<min) //若新距离小于最短距离
{
v=w; //更新v
min=D[w]; //更新最短距离
}
}
S[v]=true; //将v加入到S中
for(w=0;w<G->vexnum;++w)
if(!S[w]&&(min+G->arcs[v][w]<D[w])) //不等于自身且有最短距离
{
D[w]=min+G->arcs[v][w]; //更新最短距离
for(x=0;x<G->vexnum;++x)
path[w][x]=path[v][x]; //将自身前驱更新为v点最短距离的点
path[w][w]=1; //标记自身
}
}
cout<<" 从"<<G->vex[v0].name<<"到"<<G->vex[v1].name<<"的最短路径长度为:"<<D[v1]<<" 米"<<endl;
cout<<" 路径为:";
for(int j=0;j<G->vexnum;++j)
{
if(path[v1][j]==1)
cout<<G->vex[j].name<<"-->";
}
cout<<"导航结束"<<endl<<endl;
}
void shortsepath_Floyd(MGraph *G) //弗洛伊德求最短路径
{
int i,j,k,v0;
int D[NUM][NUM],path[NUM][NUM];
for(i=0;i<G->vexnum;++i) //各队结点之间初始已知路径及距离
for(j=0;j<G->vexnum;++j)
path[i][j]=0;
for(i=0;i<G->vexnum;++i)
for(j=0;j<G->vexnum;++j)
{
D[i][j]=G->arcs[i][j];
if(D[i][j]<MAX && i!=j) path[i][j]=i; //如果i和j之间有弧,则将j的前驱置为i
else path[i][j]=-1; //如果i和j之间无弧,则将j的前驱置为i-1
}
for(k=0;k<G->vexnum;++k)
for(i=0;i<G->vexnum;++i)
for(j=0;j<G->vexnum;++j) //从i经k到j的一条路径最短
if(D[i][k]+D[k][j]<D[i][j])
{
D[i][j]=D[i][k]+D[k][j]; //更新距离
path[i][j]=path[k][j]; //更改j的前驱为k
}
cout<<"输入起点"<<endl;
cin>>v0;
v0=v0-1;
for(i=0;i<G->vexnum;++i)
for(j=0;j<G->vexnum;++j)
if(i==v0 && j!=v0)
cout<<G->vex[v0].name<<"----->"<<G->vex[j].name<<" 的最短距离为: "<<D[i][j]<<"米"<<endl;
}
void zhupingmu() //主界面
{
cout<<" ********************欢迎来到xx大学********************"<<endl;
cout<<" 鸟瞰图 "<<endl<<endl;
cout<<" ---------------------14.北门------------------------- "<<endl;
cout<<" | | "<<endl;
cout<<" | 11.假山 12.体育馆 13.荷花池 | "<<endl;
cout<<" | | "<<endl;
cout<<" 10.西门 9.寝室 8.小西湖 6.教学楼 7.东门"<<endl;
cout<<" | | "<<endl;
cout<<" | 5.食堂 3.图书馆 4.桃花林 | "<<endl;
cout<<" | | "<<endl;
cout<<" ----------------------2.正门------------------------- "<<endl<<endl;
cout<<" 1.纪念碑 "<<endl<<endl;
cout<<" ************************************************************"<<endl<<endl;
}
char menu() // 主菜单
{
char c;
int flag;
do{
flag=true;
system("cls"); //清屏
zhupingmu();
cout<<" 很高兴为你服务:"<<endl;
cout<<" 1.景点查询(全部景点信息)" <<endl<<" 2.路线导航(最短路线)" <<endl;
cout<<" 3.景点最近距离(一点到其它点)" <<endl<<" 4.距离修改(两点之间直接路径)" <<endl;
cout<<" 5.两点直接路径(图中的边)" <<endl<<" 6.按e退出" <<endl;
cout<<" 请输入您的选择:" <<endl;
cin>>c;
if(c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='e')
flag=false;
}while(flag);
return c;
}
int main()
{
G=InitGraph(); //初始化图
char m;
zhupingmu();
do{
m=menu();
switch(m)
{
case '1': printVex(&G); cout<<"按回车键继续----";getchar();getchar();
break;
case '2': shortsepath_Dijkstra(&G); cout<<"按回车键继续-----";getchar();getchar();
break;
case '3': shortsepath_Floyd(&G); cout<<"按回车键继续----";getchar();getchar();
break;
case '4': Changes(&G); cout<<"按回车键继续----";getchar();getchar();
break;
case '5': printArc(&G); cout<<"按回车键继续----";getchar();getchar();
break;
};
}while(m!='e');
return 0;
}