C语言代码实现:采用邻接矩阵存储,实现迪杰斯特拉算法并打印出各两点之间的最短路径及距离;若规定图中若干个路径必经点,再在原来的基础上改进迪杰斯特拉算法
时间: 2024-02-23 10:03:22 浏览: 65
以下是采用邻接矩阵存储,实现迪杰斯特拉算法并打印出各两点之间的最短路径及距离,并且规定图中若干个路径必经点的C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_VERTICES 100
#define INF INT_MAX
typedef struct GraphType {
int n; // number of vertices
int weight[MAX_VERTICES][MAX_VERTICES];
} GraphType;
void init(GraphType *g) {
g->n = 0;
for (int i = 0; i < MAX_VERTICES; i++) {
for (int j = 0; j < MAX_VERTICES; j++) {
g->weight[i][j] = INF;
}
}
}
void add_edge(GraphType *g, int from, int to, int weight) {
g->weight[from][to] = weight;
}
void dijkstra(GraphType *g, int start, int end, int *required, int num_required, int **distance, int **predecessor) {
*distance = (int*)malloc(sizeof(int) * g->n);
*predecessor = (int*)malloc(sizeof(int) * g->n);
int visited[MAX_VERTICES] = {0};
for (int i = 0; i < g->n; i++) {
(*distance)[i] = INF;
}
// set start vertex distance to 0
(*distance)[start] = 0;
// update distance for all vertices
for (int count = 0; count < g->n - 1; count++) {
int u = -1;
for (int i = 0; i < g->n; i++) {
if (!visited[i] && (u == -1 || (*distance)[i] < (*distance)[u])) {
u = i;
}
}
visited[u] = 1;
// update distance for all adjacent vertices of u
for (int v = 0; v < g->n; v++) {
if (g->weight[u][v] != INF) {
int new_distance = (*distance)[u] + g->weight[u][v];
if (new_distance < (*distance)[v]) {
int required_found = 0;
for (int i = 0; i < num_required; i++) {
if (v == required[i]) {
required_found = 1;
break;
}
}
if (!required_found || (required_found && (*distance)[u] != INF)) {
(*distance)[v] = new_distance;
(*predecessor)[v] = u;
}
}
}
}
}
}
void print_path(int *predecessor, int start, int end) {
if (start == end) {
printf("%d ", start);
} else if (predecessor[end] == -1) {
printf("No path from %d to %d\n", start, end);
} else {
print_path(predecessor, start, predecessor[end]);
printf("%d ", end);
}
}
int main() {
GraphType g;
init(&g);
// add edges and weights
g.n = 7;
add_edge(&g, 0, 1, 2);
add_edge(&g, 0, 2, 4);
add_edge(&g, 1, 2, 1);
add_edge(&g, 1, 3, 3);
add_edge(&g, 2, 4, 5);
add_edge(&g, 3, 4, 1);
add_edge(&g, 3, 5, 7);
add_edge(&g, 4, 5, 1);
add_edge(&g, 4, 6, 2);
add_edge(&g, 5, 6, 3);
int required[] = {1, 3, 5};
int num_required = 3;
int *distance[MAX_VERTICES], *predecessor[MAX_VERTICES];
for (int i = 0; i < g.n; i++) {
dijkstra(&g, i, -1, required, num_required, &distance[i], &predecessor[i]);
}
printf("Shortest distances and paths:\n");
for (int i = 0; i < g.n; i++) {
for (int j = 0; j < g.n; j++) {
printf("From %d to %d: distance=%d, path=", i, j, distance[i][j]);
print_path(predecessor[i], i, j);
printf("\n");
}
}
// free memory
for (int i = 0; i < g.n; i++) {
free(distance[i]);
free(predecessor[i]);
}
return 0;
}
```
在main函数中,我们创建了一个包含7个节点的图,并且添加了相应的边和权重。然后我们调用了dijkstra函数来求从每个节点到其他节点的最短路径,其中包含必经点1、3、5。我们使用distance和predecessor数组来存储每个节点到其他节点的最短距离和前驱节点。最后,我们打印出每两个节点之间的最短路径和距离。
注意,在实际应用中,我们可能需要使用更高效的数据结构来存储图,比如邻接表等。同时,由于需要求出每个节点到其他节点的最短路径,因此时间复杂度为O(n^3),其中n为图中节点数。如果图比较稠密,邻接矩阵存储比较合适;如果图比较稀疏,邻接表存储比较合适。
阅读全文