最短路问题
实验要求
**实验题目:**校园导游咨询实验目的:掌握图的存储方法和最短路经算法。实验内容:设计一个校园导游程序,为来访客人提供各种信息查询服务。测试数据根据实际情况指定。提示:一般情况下,校园的道路是双向通行的,可设校园平面图是一个无向图。顶点和边均含有相关信息。
实验要求:
- 设计所在学校的校园平面图,所含景点不少于10个。以图中顶点表示校内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
- 为来访客人提供图中任意景点相关信息的查询。
- 为来访客人提供图中任意景点的纹路查询,即查询任意两个景点之间的一条最短的简单路径。
实验思路
- 明显的多源最短路问题,最简单的一种最短路了
- 点少路多,直接稠密图邻接矩阵,不需要邻接表村
- Floyd YYDS 拿下
设计的校园图(别偷我图!!!)
完整代码
//
// Created by CrazyBin on 2022/3/2.
//
#include "stdio.h"
#include "stdlib.h"
#include<string.h>
#include<conio.h>
#define INF 0x3f3f3f3F
FILE * map;
FILE * road;
int p_sum;
int e_sum;
typedef struct Place{
char name[20];
char s;
char detail[50];
} Pl;
typedef struct Edge{
char from;
char to;
int weight;
char name[20];
} Path;
Path path[20];
Pl place[20];
int dis[100][100];
int p[100][100];
int whatRoad(int from,int to);
void searchAll();
void menu();
void Floyd();
int getIndex(char a);
void shortest();
void initMap();
int min(int a,int b);
int getRow(FILE *f,char * __restrict__ _Filename);
int min(int a,int b)
{
if(a>b)
return b;
else
return a;
}
int getRow(FILE *f, char * __restrict__ _Filename)
{
f= fopen(_Filename,"r");
int k;
int sum=1;
while((k= fgetc(f))!=EOF)
{
if(k=='\n')
sum++;
}
fclose(f);
return sum;
}
int getIndex(char a)
{
return a-'A'+1;
}
int whatRoad(int from,int to)
{
for(int i=1;i<=e_sum;i++)
{
if(getIndex(path[i].from)==from&& getIndex(path[i].to)==to)
return i;
}
}
void shortest()
{
char a, b;
system("cls");
printf("请输入两个地点的代号:");
fflush(stdin);
scanf("%c %c",&a,&b);
int from=getIndex(a);
int to= getIndex(b);
printf("%s与%s间的最短路线长度为%d米\n",place[from].name,place[to].name,dis[from][to]);
printf("系统推荐路线为:%s",place[from].name);
int k=p[from][to];
int r;
while(k!=to)
{
r= whatRoad(from,k);
from=k;
printf("-> %s ",path[r].name);
printf("-> %s ",place[k].name);
k=p[k][to];
}
printf("-> %s ",path[r].name);
printf("-> %s \n",place[to].name);
printf("按任意键回到主菜单");
getch();
getchar();
menu();
}
void Floyd()
{
for(int i=1;i<=p_sum;i++)
{
for(int j=1;j<=p_sum;j++)
{
if(i==j)dis[i][j]=0;
else dis[i][j]=INF;
}
}
for(int i=1;i<=e_sum;i++)
{
int from= getIndex(path[i].from);
int to= getIndex(path[i].to);
int weight=path[i].weight;
dis[from][to]=dis[to][from]= min(dis[from][to],weight);
}
for(int k=1;k<=p_sum;k++)
for(int i=1;i<=p_sum;i++)
for(int j=1;j<=p_sum;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
// p[i][j]=p[i][k];
}
}
}
void initMap()
{
int row=getRow(map,"place.txt");
map= fopen("place.txt","r");
for(int i=1;i<=row;i++)
{
fscanf(map,"%s",&place[i].name);
fgetc(map);
place[i].s=fgetc(map);
fscanf(map,"%s",&place[i].detail);
p_sum++;
}
fclose(map);
row= getRow(road,"road.txt");
road= fopen("road.txt","r");
for(int i=1;i<=row;i++)
{
path[i].from=fgetc(road);
fgetc(road);
path[i].to=fgetc(road);
fscanf(road,"%s",&path[i].name);
fgetc(road);
fscanf(road,"%d",&path[i].weight);
fgetc(road);
e_sum++;
}
fclose(road);
}
int main()
{
initMap();
Floyd();
menu();
}
void searchAll()
{
system("cls");
printf("中国海洋大学各地区如下:\n");
for(int i=1;i<=p_sum;i++)
{
printf("地点: %s",place[i].name);
printf(" 代号: %c",place[i].s);
printf(" 简介: %s\n",place[i].detail);
}
printf("按任意键回到主菜单");
getch();
getchar();
menu();
}
void menu()
{
system("cls");
char n;
int x=0;
printf("------欢迎使用中国海洋大学导游系统-------\n");
printf("-----------[1]查询各地点-----------------\n");
printf("-----------[2]查询景点间的最短路径-------\n");
printf("-----------[0]退出程序-------------------\n");
do{
printf("请输入你的选择:");
n=getchar();
switch(n)
{
case '1':searchAll();break;
case '2':shortest();break;
case '0':exit(0);
default:printf("没有符合您选择的功能,请重新输入!\n");
fflush(stdin);
x=1;
}
}
while(x==1);
}
实验截图