用c语言实现如下功能:生成以南门、北门、一食堂、二食堂和教学楼为顶点的无向网;使用floyd算法求出任意两点间的最短距离,当输入任意两个顶点名称查询时输出该两点间的最短路径及距离;用迪杰斯特拉算法求出每一点点到其他各顶点的最短路径及长度,并输出
时间: 2024-01-21 15:17:49 浏览: 81
以下是用C语言实现的代码:
```c
#include <stdio.h>
#include <string.h>
#define MAX_VERTEX_NUM 5 // 顶点数目
#define MAX_DISTANCE 100 // 两点间距离的最大值
typedef enum vertex {
NANMEN = 0, // 南门
BEIMEN, // 北门
YIFANG, // 一食堂
ERFTANG, // 二食堂
JIAOXUEL, // 教学楼
} Vertex;
int distance[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 两点间距离
void init_distance() {
memset(distance, 0, sizeof(distance)); // 初始化所有距离为0
// 设置南门到其他点的距离
distance[NANMEN][BEIMEN] = 15;
distance[NANMEN][YIFANG] = 8;
distance[NANMEN][ERFTANG] = 17;
distance[NANMEN][JIAOXUEL] = 13;
// 设置北门到其他点的距离
distance[BEIMEN][YIFANG] = 11;
distance[BEIMEN][ERFTANG] = 21;
distance[BEIMEN][JIAOXUEL] = 19;
// 设置一食堂到其他点的距离
distance[YIFANG][ERFTANG] = 6;
distance[YIFANG][JIAOXUEL] = 14;
// 设置二食堂到教学楼的距离
distance[ERFTANG][JIAOXUEL] = 8;
// 将对称位置的距离设置为相同的值
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
for (int j = i+1; j < MAX_VERTEX_NUM; j++) {
distance[j][i] = distance[i][j];
}
}
}
void floyd() {
// 初始化中间节点为-1
int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
memset(path, -1, sizeof(path));
// Floyd算法核心代码
for (int k = 0; k < MAX_VERTEX_NUM; k++) {
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
for (int j = 0; j < MAX_VERTEX_NUM; j++) {
if (distance[i][j] > distance[i][k] + distance[k][j]) {
distance[i][j] = distance[i][k] + distance[k][j];
path[i][j] = k; // 记录中间节点
}
}
}
}
}
void print_path(Vertex start, Vertex end, int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM]) {
// 递归输出最短路径
if (path[start][end] == -1) {
printf("%d", end);
return;
}
print_path(start, path[start][end], path);
printf(" -> %d", end);
}
void query_shortest_path(Vertex start, Vertex end) {
printf("距离:%d\n", distance[start][end]);
printf("最短路径:");
print_path(start, end, path);
printf("\n");
}
void dijkstra(Vertex start) {
int visited[MAX_VERTEX_NUM] = {0}; // 记录是否访问过
int dist[MAX_VERTEX_NUM]; // 记录起点到各点的最短距离
int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 记录最短路径中的中间节点
// 初始化dist和path
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
dist[i] = distance[start][i];
if (dist[i] < MAX_DISTANCE) {
path[i][0] = start;
path[i][1] = i;
} else {
path[i][0] = -1;
}
}
visited[start] = 1;
for (int i = 1; i < MAX_VERTEX_NUM; i++) {
int min_dist = MAX_DISTANCE;
int min_vertex = -1;
for (int j = 0; j < MAX_VERTEX_NUM; j++) {
if (!visited[j] && dist[j] < min_dist) {
min_dist = dist[j];
min_vertex = j;
}
}
if (min_vertex == -1) {
break;
}
visited[min_vertex] = 1;
for (int j = 0; j < MAX_VERTEX_NUM; j++) {
if (!visited[j] && distance[min_vertex][j] < MAX_DISTANCE) {
if (dist[min_vertex] + distance[min_vertex][j] < dist[j]) {
dist[j] = dist[min_vertex] + distance[min_vertex][j];
path[j][0] = min_vertex;
int k;
for (k = 1; path[min_vertex][k] != -1; k++) {
path[j][k] = path[min_vertex][k];
}
path[j][k] = j;
}
}
}
}
// 输出每点到其他各点的最短路径
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
if (i == start) {
continue;
}
printf("从%d到%d的最短距离:%d,最短路径:", start, i, dist[i]);
if (path[i][0] == -1) {
printf("无法到达\n");
} else {
print_path(start, i, path);
printf("\n");
}
}
}
int main() {
init_distance();
floyd();
printf("请输入两个顶点名称查询最短路径(如:1 3):\n");
int start, end;
scanf("%d %d", &start, &end);
query_shortest_path(start-1, end-1);
printf("\n使用Dijkstra算法求每点到其他各顶点的最短路径:\n");
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
dijkstra(i);
}
return 0;
}
```
代码中使用了邻接矩阵来存储图,并使用Floyd算法求出任意两点间的最短距离。在查询最短路径时,使用递归函数输出中间节点。在使用Dijkstra算法求每点到其他各顶点的最短路径时,使用visited数组记录是否访问过,dist数组记录起点到各点的最短距离,path数组记录最短路径中的中间节点。
阅读全文
相关推荐















