主要涉及无线网创建和单源最短路径问题
设计要求:设计平面图,至少包括10个以上的场所,每两个场所间可以有不同的路,且路长也可能不同,找出从任意场所到达另一场所的最佳路径(最短路径)。
基本要求:
1)设计校园平面图,在校园景点选10个左右景点。以图中顶点表示校园内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等有关信息。
2)为来访客人提供图中任意景点相关信息的查询。
3)为来访客人提供任意景点的问路查询,即查询任意两个景点之间的一条最短路径。
实现提示:一般情况下,校园的道路是双向通行的,可设计校园平面图是一个无向网。顶点和边均含有相关信息。
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR -1
#define OVERFLOW 0
#define MAXVER 20 //定义最大定点数
#define MAXINT 200 // 无穷大
#define NULL 0
typedef char verType; //定义顶点类型
typedef int status ;
typedef struct ver //关于景点(顶点)信息存放(结构体数组)
{
char name[20]; //存放景点名称
char mask; //存放景点代号
char intro[20]; //景点简介
}Ver[MAXVER];
typedef struct //无向网存放景区信息
{
Ver verx; //定义顶点
int arcs[MAXVER][MAXVER]; //定义弧
int vernum,arcsnum; //定义最大顶点数 和弧
}MGraph;
int locate(MGraph G,verType ch) //查找顶点在数组中的下标
{
int i;
for(i=0;i<G.vernum&&ch!=G.verx[i].mask;i++);
return i;
}
status createUDN(MGraph &G,int &v) //创建无向网
{
int i,j,w,k;
verType ch1,ch2;
printf("请输入场所的个数和路径数:格式如2 3\n");
scanf("%d%d",&G.vernum,&G.arcsnum);
fflush(stdin);
printf("请输入顶点信息\n");
for(i=0;i<G.vernum;i++)
{
printf("\n请输入第%d个景点名称:\n",i+1);
scanf("%s",&G.verx[i].name);
fflush(stdin);
printf("请输入景点代号,用一个字符表示如A\n");
scanf("%c",&G.verx[i].mask);
fflush(stdin);
printf("请对景点简单介绍\n");
scanf("%s",&G.verx[i].intro);
fflush(stdin);
}
for(i=0;i<G.vernum;i++)
{
for(j=0;j<G.vernum;j++)
G.arcs[i][j]=MAXINT; //赋初值为无穷大
}
printf("请输入场所间距离:格式A B 3\\n \n");
for(i=0;i<G.arcsnum;i++)
{
printf("请输入第%d对值\n",i+1);
scanf("%c %c %d",&ch1,&ch2,&w); //输入顶点符号和权值
fflush(stdin);
k=locate(G,ch1); //获得顶点下标
j=locate(G,ch2);
G.arcs[k][j]=w; //为临界矩阵赋值
G.arcs[j][k]=G.arcs[k][j]; //无向图为对称矩阵
}
return OK;
}
void message(MGraph G) //进行信息查询
{
char mask;
printf("请输入要查询景点代号如A\n");
scanf("%c",&mask);
fflush(stdin);
for(int i=0;i<G.vernum;i++)
{
if(mask==G.verx[i].mask)
{
printf("景点名称:%s\n景点简介:%s",G.verx[i].name,G.verx[i].intro);
return;
}
}
return;
}
int search(MGraph G) //进行最短路径查询
{
char value1,value2;
int i,j; //存放两个值得下标
int q;
int all=0; //记录经过点的个数
int lujing[MAXINT][MAXINT]; //用来 记录路径
for (int m=0;m<MAXINT;m++)
for (int n=0;n<MAXINT;n++)
lujing[m][n]=NULL;
int sub;
int D[MAXVER],P[MAXVER],min;
bool final[MAXVER];
printf("\n请输入两个场所值求其最短距离和路径 如A B\n");
scanf("%c %c",&value1,&value2);
i=locate(G,value1); //获得第一个顶点下标
j=locate(G,value2); //获取第二个顶点下标
sub=i;
for(int v=0;v<G.vernum;++v) //初始化工作
{
final[v]=false; //从起始点到另外点均未找到最短路径 主要是定义一个集合将访问过的点设置值为true 刚开始集合为空
D[v]=G.arcs[i][v]; //从其余点到起始点距离(记录是最短距离 到起始点)
}
D[i]=0;final[i]=true; //起始点到起始点距离为0 起始点设置为已经访问过
P[sub]=-1;
for(int out=1;out<G.vernum;out++) //最多扩充n-1个点到已经访问过的点集
{
min=MAXINT;
for(int w=0;w<G.vernum;w++) // 在当前未选择点集中选估计距离最小的顶点k
{
if(!final[w])
if(D[w]<min) { q=w; min=D[w]; }
}
final[q]=true; //将最小距离点加入到已经访问过点集中
P[q]=sub;
for( w=0;lujing[q][w]!=NULL;w++){}
lujing[q][w]=q;
for(int m=0;m<G.vernum;m++) //调整剩余点到起始点的估计距离
{
if(!final[m]&&(min+G.arcs[q][m]<D[m]))
{
D[m]=min+G.arcs[q][m];sub=q;
P[m]=sub;
for( w=0;lujing[q][w]!=NULL ;w++)
lujing[m][w]=lujing[q][w];
for(;lujing[m][w]!=NULL;w++)
lujing[m][w]=NULL;
}
}
if(q==j)
{
printf("最短路径为%d\n",D[j]);
printf("依次经过景区为:");
printf("%c ",value1);
for (int c=0;lujing[j][c]!=NULL;c++)
{
printf("%c ",G.verx[lujing[j][c]].mask);
}
}
}
return 0;
}
int main()
{
MGraph G;
int v=0;
int alter;
printf("请先输入建立校园图所需要的信息:\n\n");
if(createUDN(G,v)) //创建无向网
{
do
{
printf("\n\n查询某个景点信息请输入1\n");
printf("查询两个景点之间最短距离请输入2\n");
printf("退出请输入0\n");
scanf("%d",&alter);
fflush(stdin);
switch(alter)
{
case 0:return 0; break;
case 1: message(G);break;
case 2:search(G);break;
}
}while(alter);
}
return 0;
}
运行结果