用c语言编写求起始点1到N的最短路径. Input 多组测试数据,对于每组数据 第一行是两个整数N, M。分别代表定点的数个和边的关系的个数。 从第二行至M+1行,每行三个整数,start, end, value。代表,节点start,节点end之间有一条长度为value的无向边。求1到N的最短路径。 (M, N, start, end, value < 100) Output 对于每组测试数据,输出一个整数result,代表1至N的最短路径的value。 Sample Input 5 5 1 2 1 2 4 2 4 5 1 1 3 1 3 5 2 Sample Output 3
时间: 2024-03-22 20:39:02 浏览: 75
这是一道经典的最短路径问题,可以使用 Dijkstra 或者 Floyd 算法来解决。
以下是 Dijkstra 算法的 C 代码实现:
```c
#include <stdio.h>
#include <string.h>
#define MAXN 100
#define INF 0x3f3f3f3f
int graph[MAXN][MAXN]; // 存储图
int dist[MAXN]; // 存储起点到各个点的最短距离
int visited[MAXN]; // 标记是否已经访问
void dijkstra(int n, int start) {
memset(dist, INF, sizeof(dist)); // 初始化为无穷大
memset(visited, 0, sizeof(visited)); // 初始化为未访问
dist[start] = 0; // 起点到自身的距离为0
for (int i = 1; i <= n; i++) {
int min_dist = INF, min_node = -1;
// 找到未访问节点中距离最小的节点
for (int j = 1; j <= n; j++) {
if (!visited[j] && dist[j] < min_dist) {
min_dist = dist[j];
min_node = j;
}
}
if (min_node == -1) break; // 找不到可达节点,退出循环
visited[min_node] = 1; // 标记该节点为已访问
// 更新与该节点相邻的节点的最短距离
for (int j = 1; j <= n; j++) {
if (!visited[j] && graph[min_node][j] != INF) {
dist[j] = dist[j] < dist[min_node] + graph[min_node][j] ? dist[j] : dist[min_node] + graph[min_node][j];
}
}
}
}
int main() {
int n, m;
while (scanf("%d%d", &n, &m) == 2) {
memset(graph, INF, sizeof(graph)); // 初始化为无穷大
// 读入边的信息
for (int i = 1; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
graph[u][v] = graph[v][u] = w; // 无向图
}
dijkstra(n, 1); // 求1到n的最短距离
printf("%d\n", dist[n]);
}
return 0;
}
```
以上代码中,`graph` 数组用于存储图的边信息,`dist` 数组用于存储起点到各个点的最短距离,`visited` 数组用于标记节点是否已经访问过。
Dijkstra 算法的时间复杂度为 $O(n^2)$,适用于稠密图。如果图比较稀疏,可以使用更快的优先队列优化的 Dijkstra 算法,时间复杂度为 $O(m\log n)$,但实现起来比较复杂。另外,Floyd 算法也可以求解最短路径问题,但时间复杂度为 $O(n^3)$,比较适用于小规模的图。
阅读全文