有一个 n 个点 m 条边的无向图,请求出从 s 到 t 的最短路长度。要求第一行四个正整数 n, m, s, t。 接下来 m 行,每行三个正整数 u, v, w,表示一条连接 u, v长为 w 的边。 1≤n≤2500,1≤m≤6200,1≤w≤1000。输出一行一个整数,表示答案。用C语言编写
时间: 2024-01-22 19:18:41 浏览: 111
C 代码 实现贝尔曼-福特算法以查找最短的 从给定节点到有向图中所有其他节点的距离 其边已分配实值长度.rar
以下是使用Dijkstra算法求解的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_N 2500
#define MAX_M 6200
struct Edge {
int to, weight, next;
};
struct Graph {
struct Edge edges[MAX_M * 2];
int head[MAX_N + 1], edge_count;
};
struct HeapNode {
int node, dist;
};
struct Heap {
struct HeapNode nodes[MAX_N + 1];
int size;
};
struct Graph graph;
int n, m, s, t;
int dist[MAX_N + 1];
int visited[MAX_N + 1];
void add_edge(int from, int to, int weight) {
graph.edges[++graph.edge_count] = (struct Edge){to, weight, graph.head[from]};
graph.head[from] = graph.edge_count;
}
void heap_push(struct Heap *heap, struct HeapNode node) {
heap->nodes[++heap->size] = node;
int i = heap->size;
while (i > 1 && heap->nodes[i].dist < heap->nodes[i / 2].dist) {
struct HeapNode temp = heap->nodes[i];
heap->nodes[i] = heap->nodes[i / 2];
heap->nodes[i / 2] = temp;
i /= 2;
}
}
struct HeapNode heap_pop(struct Heap *heap) {
struct HeapNode result = heap->nodes[1];
heap->nodes[1] = heap->nodes[heap->size--];
int i = 1;
while (i * 2 <= heap->size) {
int child = i * 2;
if (child + 1 <= heap->size && heap->nodes[child + 1].dist < heap->nodes[child].dist) {
child++;
}
if (heap->nodes[i].dist > heap->nodes[child].dist) {
struct HeapNode temp = heap->nodes[i];
heap->nodes[i] = heap->nodes[child];
heap->nodes[child] = temp;
i = child;
} else {
break;
}
}
return result;
}
void dijkstra() {
struct Heap heap = {0};
heap_push(&heap, (struct HeapNode){s, 0});
for (int i = 1; i <= n; i++) {
dist[i] = INT_MAX;
}
dist[s] = 0;
while (heap.size > 0) {
struct HeapNode min_node = heap_pop(&heap);
if (visited[min_node.node]) {
continue;
}
visited[min_node.node] = 1;
for (int i = graph.head[min_node.node]; i != 0; i = graph.edges[i].next) {
int next_node = graph.edges[i].to;
int next_dist = min_node.dist + graph.edges[i].weight;
if (next_dist < dist[next_node]) {
dist[next_node] = next_dist;
heap_push(&heap, (struct HeapNode){next_node, next_dist});
}
}
}
}
int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i = 1; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add_edge(u, v, w);
add_edge(v, u, w);
}
dijkstra();
printf("%d\n", dist[t]);
return 0;
}
```
首先定义了一个结构体 `Edge` 表示一条边,包含了指向的节点编号、边的长度和下一条边的编号,用于构建邻接表。然后定义了结构体 `Graph` 表示整个图,包含了邻接表和边的数量。接着定义了结构体 `HeapNode` 表示堆中的一个节点,包含了节点编号和到起点的距离。定义了结构体 `Heap` 表示堆,包含了堆中的所有节点和节点的数量。定义了一个 `add_edge` 函数向邻接表中添加一条边。定义了 `heap_push` 和 `heap_pop` 函数分别向堆中插入一个节点和弹出堆顶的节点。定义了 `dijkstra` 函数使用 Dijkstra 算法求解最短路。最后在 `main` 函数中读入图的信息,调用 `dijkstra` 函数求解最短路并输出结果。
阅读全文