用C语言写一段代码并且有注释,游客通过终端询问可知,要求:(1)将导游图看作一张带权无向图,顶点表示公园的各个景点,边表示各景点之间的道路,边上的权值表示距离,选择适当的数据结构。 (2)为游客提供图中任意景点相关信息的查询。 (3)为游客提供任意两个景点之间最短的简单路径。 (4)为游客选择最佳游览路径。(5)以邻接表为存储结构,利用Dijkstra算法或Floy算法求最短路径,利用搜索求最佳路径。

时间: 2024-02-05 08:14:10 浏览: 27
以下是基于邻接表的图的最短路径查询和最佳路径选择的C语言代码,包括注释: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_VERTICES 100 // 最大顶点数 #define INF 1000000 // 无穷大的距离(即不存在的边的距离) // 邻接表中的边结构体 typedef struct Edge { int dest; // 目标顶点的下标 int weight; // 边的权重(距离) struct Edge *next; // 指向下一个邻接点的指针 } Edge; // 邻接表中的顶点结构体 typedef struct Vertex { char name[20]; // 顶点的名称 Edge *head; // 指向第一个邻接点的指针 } Vertex; // 图结构体 typedef struct Graph { int num_vertices; // 顶点数 Vertex vertices[MAX_VERTICES]; // 顶点数组 } Graph; // 初始化一个图 void init_graph(Graph *graph) { graph->num_vertices = 0; for (int i = 0; i < MAX_VERTICES; i++) { graph->vertices[i].head = NULL; } } // 添加一个顶点到图中 void add_vertex(Graph *graph, const char *name) { Vertex *v = &graph->vertices[graph->num_vertices++]; strcpy(v->name, name); v->head = NULL; } // 添加一条边到图中 void add_edge(Graph *graph, int src, int dest, int weight) { Edge *e = (Edge*) malloc(sizeof(Edge)); e->dest = dest; e->weight = weight; e->next = graph->vertices[src].head; graph->vertices[src].head = e; } // Dijkstra算法求最短路径 void dijkstra(Graph *graph, int start, int distances[], int prev[]) { int i, j, k, min_distance; int visited[MAX_VERTICES]; // 初始化距离和前驱数组 for (i = 0; i < graph->num_vertices; i++) { distances[i] = INF; prev[i] = -1; visited[i] = 0; } distances[start] = 0; // 遍历所有顶点 for (i = 0; i < graph->num_vertices; i++) { // 找到未访问过的距离最短的顶点 min_distance = INF; for (j = 0; j < graph->num_vertices; j++) { if (!visited[j] && distances[j] < min_distance) { min_distance = distances[j]; k = j; } } visited[k] = 1; // 更新所有邻接点的距离和前驱 for (Edge *e = graph->vertices[k].head; e != NULL; e = e->next) { j = e->dest; if (!visited[j] && distances[k] + e->weight < distances[j]) { distances[j] = distances[k] + e->weight; prev[j] = k; } } } } // 打印最短路径 void print_path(Graph *graph, int start, int end, int prev[]) { if (start == end) { printf("%s", graph->vertices[start].name); return; } print_path(graph, start, prev[end], prev); printf(" -> %s", graph->vertices[end].name); } // 选择最佳路径 void search_path(Graph *graph, int start, int end, int distances[], int prev[], int visited[], int path[], int *path_len, int *path_distance) { int i, j, k, min_distance; // 标记起点和终点已访问 visited[start] = 1; visited[end] = 1; // 初始化路径数组和路径长度 path[0] = start; *path_len = 1; *path_distance = 0; // 在未访问的点中找到到已访问点距离最短的顶点,加入路径中 while (*path_len < graph->num_vertices) { min_distance = INF; for (i = 0; i < *path_len; i++) { k = path[i]; for (Edge *e = graph->vertices[k].head; e != NULL; e = e->next) { j = e->dest; if (!visited[j] && e->weight < min_distance) { min_distance = e->weight; path[*path_len] = j; } } } if (min_distance == INF) { // 找不到更多的未访问点了 break; } visited[path[*path_len]] = 1; *path_len += 1; *path_distance += min_distance; } // 如果终点不在路径中,则将终点加入路径 if (path[*path_len - 1] != end) { path[*path_len] = end; *path_len += 1; } } int main() { Graph graph; int distances[MAX_VERTICES]; int prev[MAX_VERTICES]; int visited[MAX_VERTICES]; int path[MAX_VERTICES]; int path_len, path_distance; init_graph(&graph); // 添加顶点 add_vertex(&graph, "Entrance"); add_vertex(&graph, "Lake"); add_vertex(&graph, "Mountain"); add_vertex(&graph, "Forest"); add_vertex(&graph, "Valley"); // 添加边 add_edge(&graph, 0, 1, 20); add_edge(&graph, 0, 2, 30); add_edge(&graph, 0, 3, 15); add_edge(&graph, 1, 2, 10); add_edge(&graph, 1, 3, 25); add_edge(&graph, 2, 4, 20); add_edge(&graph, 3, 4, 10); // 查询景点信息 printf("Which vertex do you want to know? "); char name[20]; scanf("%s", name); for (int i = 0; i < graph.num_vertices; i++) { if (strcmp(graph.vertices[i].name, name) == 0) { printf("Vertex %s:\n", name); printf(" Adjacent vertices:"); for (Edge *e = graph.vertices[i].head; e != NULL; e = e->next) { printf(" %s", graph.vertices[e->dest].name); } printf("\n"); break; } } // 查询最短路径 printf("Which two vertices do you want to find the shortest path between? "); char name1[20], name2[20]; scanf("%s %s", name1, name2); int start = -1, end = -1; for (int i = 0; i < graph.num_vertices; i++) { if (strcmp(graph.vertices[i].name, name1) == 0) { start = i; } if (strcmp(graph.vertices[i].name, name2) == 0) { end = i; } } if (start != -1 && end != -1) { dijkstra(&graph, start, distances, prev); printf("The shortest path from %s to %s is:\n", name1, name2); print_path(&graph, start, end, prev); printf("\n"); printf("The distance is %d.\n", distances[end]); } else { printf("Cannot find the vertices.\n"); } // 选择最佳路径 printf("Choose the vertices you want to visit in order: "); int path_vertices[MAX_VERTICES]; int num_path_vertices = 0; while (scanf("%s", name) == 1) { for (int i = 0; i < graph.num_vertices; i++) { if (strcmp(graph.vertices[i].name, name) == 0) { path_vertices[num_path_vertices++] = i; break; } } } if (num_path_vertices > 1) { // 初始化访问数组 for (int i = 0; i < graph.num_vertices; i++) { visited[i] = 0; } // 对每一段路径使用Dijkstra算法求最短距离 int total_distance = 0; for (int i = 0; i < num_path_vertices - 1; i++) { dijkstra(&graph, path_vertices[i], distances, prev); total_distance += distances[path_vertices[i + 1]]; } // 使用搜索选择最佳路径 search_path(&graph, path_vertices[0], path_vertices[num_path_vertices - 1], distances, prev, visited, path, &path_len, &path_distance); printf("The best path to visit these vertices is:\n"); for (int i = 0; i < path_len; i++) { printf("%s", graph.vertices[path[i]].name); if (i < path_len - 1) { printf(" -> "); } } printf("\n"); printf("The total distance is %d.\n", total_distance); } else { printf("Please input at least two vertices.\n"); } return 0; } ``` 这个程序可以在终端中运行,用户可以通过输入不同的命令来查询图中的信息。其中,输入数字、图中顶点的名称等信息时,需要按照程序中规定的格式输入。

相关推荐

最新推荐

recommend-type

C语言求解无向图顶点之间的所有最短路径

主要为大家详细介绍了C语言求解无向图顶点之间的所有最短路径,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

在C语言中输入一个大写字母,将其转变成一个小写字母,并且有相应的提示。

1.学习简单的C语言编程
recommend-type

c语言文件操作常用函数及读写文件代码举列

文章主要例举一个c语言文件操作常用函数及读写文件的代码,感性趣的朋友可以看看。
recommend-type

C语言版二值图像统计连通区域

主要为大家详细介绍了C语言版二值图像统计连通区域的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

C语言统计一篇英文短文中单词的个数实例代码

本文通过实例代码给大家介绍的C语言统计一篇英文短文中单词的个数,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

SPDK_NVMF_DISCOVERY_NQN是什么 有什么作用

SPDK_NVMF_DISCOVERY_NQN 是 SPDK (Storage Performance Development Kit) 中用于查询 NVMf (Non-Volatile Memory express over Fabrics) 存储设备名称的协议。NVMf 是一种基于网络的存储协议,可用于连接远程非易失性内存存储器。 SPDK_NVMF_DISCOVERY_NQN 的作用是让存储应用程序能够通过 SPDK 查询 NVMf 存储设备的名称,以便能够访问这些存储设备。通过查询 NVMf 存储设备名称,存储应用程序可以获取必要的信息,例如存储设备的IP地址、端口号、名称等,以便能
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。