[问题描述]:
当我们参观某校园时,就会遇到这样一-个问题: 从当前所处位置出发去校园另外某个位置,要走什么样的路线距离最近?本课程设计实例在给出校园各主要建筑的名称信息及有路线连通的建筑物之间的距离的基础上,利用校园导航系统计算出给定的起点到终点之间的距离最近的行进路线。
[设计要求]:
(1)从地图文件中读取校园主要建筑信息及建筑间的距离信息
(2)计算出给定的起点到终点之间的距离最近的行进路线
(3)输出该路线(包含路过哪些建筑)及其总距离
(4)若输入错误,则给出提示信息
思路如下:
源代码如下:
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define Max 10000
#define NUM 13
//边的描述
typedef struct ArcCell {
int adj; //权值
char *info; //描述
} ArcCell;
//图的结构体
typedef struct {
ArcCell arcs[NUM][NUM]; //边
int vexnum, arcnum;
char s[100][100]; // 顶点描述
} MGraph;
struct HZ {
char ch[13][30];
};
MGraph G;
int P[NUM][NUM];
long int D[NUM];
int x[13] = {0};
void CreateUDN(int v, int a);
void pingmu(struct HZ T);
void ShortestPath(int num);
void output(int sight1, int sight2, struct HZ T);
char Menu(struct HZ T);
void NextValue(int);
void display(struct HZ T);
struct HZ fun();
int main() { // 主函数
int i;
struct HZ T = fun();
int v0, v1;
char ck;
CreateUDN(NUM, 13);
strcpy(G.s[1],"兰天公寓是宿舍");
strcpy(G.s[2],"西门");
strcpy(G.s[3],"西苑餐厅,吃饭");
strcpy(G.s[4],"西操场,锻炼");
strcpy(G.s[5],"东操场");
strcpy(G.s[6],"教学九号楼");
strcpy(G.s[7],"教学三号楼");
strcpy(G.s[8],"计算机科学与工程学院");
strcpy(G.s[9],"教学七号楼");
strcpy(G.s[10],"教学一号楼");
strcpy(G.s[11],"教学十号楼");
strcpy(G.s[12],"行政一号楼");
strcpy(G.s[13],"西门");
do {
ck = Menu(T);
// pingmu(T);
if(ck=='1')
{
printf("\n\t\t\t请选择出发地序号(1~12):");
scanf("%d", &v0);
printf("\t\t\t请选择目的地序号(1~12):");
scanf("%d", &v1);
ShortestPath(v0);
output(v0, v1, T);
}
else if(ck=='3')
{
int temp;
printf("\n\t\t\t请选择景点序号(1~12):\n\t\t\t");
scanf("%d",&temp);
printf("\t\t\t%s",G.s[temp]);
}
else if(ck=='2') return 0;
else
{
printf("\n\t\t\t\t请重新输入\t\t\t\t\n");
}
printf("\n\n\t\t\t\t请按回车键继续...\n");
getchar();
getchar();
} while (ck != 'e');
return 0;
}
char Menu(struct HZ T) { // 主菜单
char c;
int flag;
do {
flag = 1;
pingmu(T);
printf("\n\t\t****************************************\n");
printf("\t\t欢迎使用西北师范大学导航图系统\n");
printf("\t\t 1.查询地点路径 \n");
printf("\t\t 2.退出 \n");
printf("\t\t 3.景点介绍 \n");
printf("\t\t****************************************\n");
printf("\t\t\t请输入您的选择:");
scanf("%c", &c);
if (c == '1' || c == '2'|| c=='3')
flag = 0;
if (flag != 0)
printf("请重新输入");
} while (flag);
return c;
}
struct HZ fun() {
char cha[800];
struct HZ T;
FILE *f;
f = fopen("txt.txt", "r");
fgets(cha, 800, f);
fclose(f);
int i = 0, a2 = 0, b2 = 0;
//初始化
for (; a2 < 13; a2++) {
for (; b2 < 30; b2++) {
T.ch[a2][b2] = '\0';
}
b2 = 0;
}
a2 = 0, b2 = 0;
while (cha[i] != '\0') {
if (cha[i] != '#') {
T.ch[a2][b2] = cha[i];
b2++;
} else {
a2++;
b2 = 0;
}
i++;
}
return T;
};
void display(struct HZ T) {
int a2 = 0;
int b2 = 0;
for (; a2 < 13; a2++) {
printf("\t\t\t(%2d) ", a2);
for (; T.ch[a2][b2] != '\0'; b2++) {
printf("%c", T.ch[a2][b2]);
}
b2 = 0;
printf("\n");
}
}
void CreateUDN(int v, int a) { // 创建图的函数
int i, j;
G.vexnum = v;
G.arcnum = a;
for (i = 1; i < G.vexnum; ++i) {
for (j = 1; j < G.vexnum; ++j) {
G.arcs[i][j].adj = Max;
G.arcs[i][j].info = NULL;
}
}
FILE *fp = fopen("long.txt", "r");
int n, m, l;
char ch;
i = 0;
while (i < 17) {
fscanf(fp, "%d", &n);
fscanf(fp, "%d", &m);
fscanf(fp, "%d", &l);
G.arcs[n][m].adj = G.arcs[m][n].adj = l;
i++;
}
fclose(fp);
}
void pingmu(struct HZ T) { // 输出函数
int i;
printf(" 西北师范大学景点概况\n\n");
printf("\t\t****************************************\n\n");
// for(i=0; i<NUM; i++) {
// printf("(%2d)%-20s\n",i,G.vex[i].sight);
// printf("(%2d)%-20s\n",i,T.ch[i]);
display(T);
// }
}
void ShortestPath(int num) { // 迪杰斯特拉算法最短路径
int v, w, i, t;
int final[NUM];
int min;
for (v = 1; v < NUM; v++) {
final[v] = 0;
D[v] = G.arcs[num][v].adj;
for (w = 1; w < NUM; w++)
P[v][w] = 0;
if (D[v] < 10000) {
P[v][num] = 1;
P[v][v] = 1;
}
}
D[num] = 0;
final[num] = 1;
for (i = 1; i < NUM; ++i) {
min = Max;
for (w = 1; w < NUM; ++w)
if (!final[w])
if (D[w] < min) {
v = w;
min = D[w];
}
final[v] = 1;
for (w = 1; w < NUM; ++w)
if (!final[w] && ((min + G.arcs[v][w].adj) < D[w])) {
D[w] = min + G.arcs[v][w].adj;
for (t = 0; t < NUM; t++)
P[w][t] = P[v][t];
P[w][w] = 1;
}
}
}
void output(int sight1, int sight2, struct HZ T) { // 输出函数
int a, b, c, d, q = 0;
a = sight2;
if (a != sight1) {
printf("\n\t\t从%s到%s的最短路径是", T.ch[sight1], T.ch[sight2]);
printf("\t(最短距离为 %dm.)\n\n\t", D[a]);
printf("\t%s", T.ch[sight1]);
d = sight1;
for (c = 0; c < NUM; ++c) {
gate:
P[a][sight1] = 0;
for (b = 0; b < NUM; b++) {
if (G.arcs[d][b].adj < 10000 && P[a][b]) {
printf("-->%s", T.ch[b]);
q = q + 1;
P[a][b] = 0;
d = b;
if (q % 8 == 0) printf("\n");
goto gate;
}
}
}
}
}
创建的外部读取文件有两个,一个是txt.txt,用来存取校园的主要建筑信息;另一个是long.txt,用来存取校园的图所代表的的权值;
txt.txt内容如下:
long.txt内容如下: