#include <iostream>
using namespace std;
#define jida 40000
typedef struct
{
char name[3000]; //结点名称
char jianjie[15000];
int num; //结点编号
}Vertex; //结构体定义顶点
typedef struct
{
Vertex vexs[11]; //结点
int arc[20][20]; //两点间的弧线权值,也称路程
int vnum, e; //图中顶点个数和边数
}Graph; //结构体定义图
Graph* CreateGraph() //初始化图
{
Graph* G;
int i,j,k;
G = (Graph*)malloc(sizeof(Graph));
G -> e = 18;
G->vnum = 10; // 图有十个顶点
for (i = 1; i <= G->vnum; i++)
G->vexs[i].num = i; //初始化顶点编号为1-10
for (j = 1; j <= 10; j++)
for (k = 1; k <= 10; k++)
{
G->arc[j][k] = jida; // 初始化每两个点间的距离为极大值
}
G->arc[1][2] = G->arc[2][1] = 60; //用邻接矩阵存储两点间的权值,依次赋值存储
G->arc[1][5] = G->arc[5][1] = 40; // 未在此赋值的弧,其权值为之前初始化的极大值
G->arc[1][4] = G->arc[4][1] = 50;
G->arc[2][5] = G->arc[5][2] = 20;
G->arc[2][3] = G->arc[3][2] = 500;
G->arc[4][6] = G->arc[6][4] = 10;
G->arc[4][5] = G->arc[5][4] = 35;
G->arc[3][5] = G->arc[5][3] = 260;
G->arc[3][7] = G->arc[7][3] = 270;
G->arc[5][7] = G->arc[7][5] = 10;
G->arc[7][8] = G->arc[8][7] = 30;
G->arc[7][9] = G->arc[9][7] = 100;
G->arc[8][9] = G->arc[9][8] = 200;
G->arc[6][8] = G->arc[8][6] = 350;
G->arc[5][8] = G->arc[8][5] = 20;
G->arc[5][10] = G->arc[10][5] = 100;
G->arc[6][10] = G->arc[10][6] = 120;
G->arc[8][10] = G->arc[10][8] = 80;
G->arc[3][10] = G->arc[10][3] = 280;
strcpy_s(G->vexs[1].name, "校医院"); //存储图中每个点的名字,依次赋值存储
strcpy_s(G->vexs[2].name, "南操场");
strcpy_s(G->vexs[3].name, "12号宿舍楼");
strcpy_s(G->vexs[4].name, "教职工餐厅");
strcpy_s(G->vexs[5].name, "图书馆");
strcpy_s(G->vexs[6].name, "北操场");
strcpy_s(G->vexs[7].name, "中央区教学楼");
strcpy_s(G->vexs[8].name, "思源堂");
strcpy_s(G->vexs[9].name, "校门");
strcpy_s(G->vexs[10].name, "品慧楼");
strcpy_s(G->vexs[1].jianjie, "(校医院位于北操附近,是学校唯一的医院)"); //为图中每个景点存储关于它的简介
strcpy_s(G->vexs[2].jianjie, "(南操场是田径场,常在此举行运动会,动员会等仪式)");
strcpy_s(G->vexs[3].jianjie, "(12号宿舍楼是男生宿舍楼,所有的信息学院男生就寝的地方)");
strcpy_s(G->vexs[4].jianjie, "(教职工餐厅位于中央区东北方位,临近考研楼)");
strcpy_s(G->vexs[5].jianjie, "(图书馆是借阅图书的地方,在二楼小阅或者三楼大阅都可以进行自习)");
strcpy_s(G->vexs[6].jianjie, "(北操场有许多篮球框,可以打篮球或者打排球)");
strcpy_s(G->vexs[7].jianjie, "(是上课的主要地方)");
strcpy_s(G->vexs[8].jianjie, "(中央区主餐厅)");
strcpy_s(G->vexs[9].jianjie, "(校门在南面)");
strcpy_s(G->vexs[10].jianjie, "(女生宿舍楼,标志性建筑)");
return G;
}
Graph* short_path_floyd(Graph* G, int p[20][20], int d[20][20]) // 弗洛伊德算法,求最短路径
{
int v, w, k; // v,w,k分别表示出发点,目的地,新加入的点
for (v = 1; v <= G->vnum; v++) {
for (w = 1; w <= G->vnum; w++)
{
d[v][w] = G->arc[v][w]; // d[20][20]代表两点间最短路径,初始化为两点间权值
p[v][w] = w; // p[20][20]记录最短路径的前一个点
}
}
for (k = 1; k <= 10; k++) //利用三阶循环,找出每两个点的最短路径
{
for (v = 1; v <= 10; v++)
{
for (w = 1; w <= 10; w++)
{
if (d[v][w] > (d[v][k] + d[k][w]))
{
d[v][w] = d[v][k] + d[k][w];
p[v][w] = p[v][k];
/* 如果新加入的点组成的路径小于最小路径,更新最小路径,
并且将新加入的点加入最短路径中 */
}
}
}
}
return G; // 返回图的类型
}
void print() // 界面函数
{
cout<<"\n\n\n"<<endl;
cout << "\t****************************************\t\n" << endl;
cout<<"\t* sdau校园导航系统 *\t\n"<<endl;
cout<<"\t****************************************\t\n"<<endl;
cout<<"\t* 1.景点信息查询 *\t\n"<<endl;
cout << "\t* 2.路线信息查询 *\t\n" << endl;
cout<<"\t* 3.退出系统 *\t\n"<<endl;
cout<<"\t****************************************\t\n"<<endl;
cout<<"\n\n请选择你需要的功能,输入代号:\n"<<endl;
}
int main()
{
int c, i, f, k, l; // f,k分别为出发点与目的地编号
Graph* T;
int q, w;
int d[20][20]; // d[20][20]代表两点间最短路径
int p[20][20]; // p[20][20]记录最短路径的前一个点
system("color 03"); // 改变输出界面颜色
for (q = 1; q <= 10; q++)
for (w = 1; w <= 10; w++)
{
d[q][w] = jida; // 任意两点间最短路径初始化为极大值
}
T = CreateGraph(); // 调用函数初始化图
T = short_path_floyd(T, p, d); //调用函数求最短路径
while (1)
{
print(); // 输出界面栏
cin>>c; //接受选项
while (c > 3 || c < 1)
{
cout<<"输入错误,请重新输入:\n"<<endl;
cin>>c;
}
if (c == 1)
{
cout<<"\n共有以下十处景点:\n"<<endl;
for (i = 1; i <= 10; i++)
{
cout<<T->vexs[i].num<<endl; //输出景点编号
cout<<T->vexs[i].name<<endl; //输出景点名字
cout<<T->vexs[i].jianjie<<endl; // 输出景点简介
}
}
else if (c == 2)
{
cout << "请输入当前景点编号和你想要去的景点编号(空格隔开):\n" << endl;
cin>>f>>k; // f,k分别接受出发点与目的地编号
while (f < 1 || f>10 || k < 1 || k>10) //非法输入
{
cout<<"输入错误,请重新输入:\n"<<endl;
cin>>f>>k;
}
if (f == k) //非法输入
{
cout<<"输入错误,你已经在此地,请重新输入:\n"<<endl;
cin>>f>>k;
}
cout<<T->vexs[f].name<<"->"<<T->vexs[k].name<<"的最小路径为:"<< d[f][k]<<"米"<<endl;
l = p[f][k]; // l作为中间变量用来接受最短路径中的父亲节点
cout<<"最短路径为:"<<T->vexs[f].name; // 输出最短路径
while (l != k)
{
cout<<"->"<< T->vexs[l].name<<endl;
l = p[l][k]; // 不断更新l节点
}
cout<<"->"<<T->vexs[k].name<<endl;
}
else
break; //退出程序
}
}
实现结果: