void ShortestPath_DIJ(MGraph G, int start,int count) { //用Dijkstra算法求有向网G的start顶点到其余顶点的最短路径 bool S[MaxVertexNum]; WeightType Path[MaxVertexNum] = { 0 }; for (int i = 0; i < count; i++) { S[i] = false;//S初始为空集 if (G.arcs[start][i]<MaxInt) { Path[i] = start; } else { Path[i] = -1; } } cout<<Path[0]<<endl; cout<<Path[1]<<endl; for(int i = 0;i<count;i++) { cout<<Path[i]<<" "; } S[start] = true; G.arcs[start][start] = 0; for (int i = 1; i < count; i++) { int min = MaxInt; for(int j = 0; j < count; j++) { if (!S[j] && G.arcs[start][j] < min) { i = j; min = G.arcs[start][j]; } } S[i] = true; for (int j = 0; j < count; j++) { if (!S[j] && (G.arcs[start][i] + G.arcs[i][j]) < G.arcs[start][j]) { G.arcs[start][j] = G.arcs[start][i] + G.arcs[i][j]; Path[j] = i; } } } } 这段代码Path数组有赋值,但为什么Path数组里面没有存内容,打印出来都是0
时间: 2023-12-18 19:02:08 浏览: 70
在这段代码中,Path数组初始值为0,但在算法执行过程中,它的值可能会被修改,即记录从起点到其他节点的最短路径中,每个节点的前驱节点。因此,Path数组在算法结束后,应该存储的是从起点到每个节点的最短路径上的前驱节点。
在这段代码中,可以看到在算法开始时,已经对Path数组进行了初始化。在算法执行过程中,当发现从起点到某个节点的路径更短时,就将该节点的前驱节点更新为当前节点。这个更新操作在代码中体现为:
```c++
if (!S[j] && (G.arcs[start][i] + G.arcs[i][j]) < G.arcs[start][j]) {
G.arcs[start][j] = G.arcs[start][i] + G.arcs[i][j];
Path[j] = i;
}
```
其中,如果从起点到i节点的距离加上从i节点到j节点的距离比从起点到j节点的距离更短,就将G.arcs[start][j]更新为这个更短的距离,并将Path[j]更新为i,表示从起点到j节点的最短路径上的前驱节点是i。
因此,在算法执行结束后,Path数组中应该存储的是从起点到每个节点的最短路径上的前驱节点,而不是最短路径的距离。如果想要输出最短路径的距离,需要在算法执行结束后,再次遍历Path数组,根据前驱节点递推出最短路径的距离。
相关问题
void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D) { int v,w,i,j,min; int final[MAX_VERTEX_NUM]; for(v=0; v<G.vexnum; ++v) { final[v]=0; (*D)[v]=G.arcs[v0][v].adj; for(w=0; w<G.vexnum; ++w) (*P)[v][w]=0; // 设空路径 if((*D)[v]<INFINITY) { (*P)[v][v0]=1; (*P)[v][v]=1; } } (*D)[v0]=0; final[v0]=1; // 初始化,v0顶点属于S集 for(i=1; i<G.vexnum; ++i) // 其余G.vexnum-1个顶点 { // 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 min=INFINITY; // 当前所知离v0顶点的最近距离 for(w=0; w<G.vexnum; ++w) if(!final[w]) // w顶点在V-S中 if((*D)[w]<min) { v=w; min=(*D)[w]; } // w顶点离v0顶点更近 final[v]=1; // 离v0顶点最近的v加入S集 for(w=0; w<G.vexnum; ++w) // 更新当前最短路径及距离 { if(!final[w]&&min<INFINITY && G.arcs[v][w].adj < INFINITY && (min+G.arcs[v][w].adj<(*D)[w])) { // 修改D[w]和P[w],w∈V-S (*D)[w]=min+G.arcs[v][w].adj; for(j=0; j<G.vexnum; ++j) (*P)[w][j]=(*P)[v][j]; (*P)[w][w]=1; } } } }实现思路
这段代码实现了Dijkstra算法,用于求解有向图中某个顶点v0到其他所有顶点的最短路径。具体实现过程如下:
1. 初始化final数组,表示该顶点是否已经加入到S集中。D数组表示v0到该顶点的最短距离,P数组表示v0到该顶点的最短路径。
2. 将v0加入到S集中,更新与v0直接相邻的顶点的最短路径和路径矩阵P。
3. 在剩余的顶点中,找到距离v0最近的顶点v,将v加入到S集中。
4. 更新与v直接相邻的顶点w的最短路径和路径矩阵P。
5. 重复步骤3、4,直到所有顶点都加入到S集中,最短路径和路径矩阵P也更新完成。
6. 返回最短路径和路径矩阵P。
这段代码使用了邻接矩阵来存储图,其中INFINITY表示两个顶点之间不存在边。
【问题描述】最短路径问题实际上是带权有向图(网)的一种应用,用Dijkstra算法求两个顶点间的最短路径。备注:输入的有向网信息中0表示不存在顶点到自身的弧,32767表示两个顶点之间不存在弧。 【输入形式】带权有向图(网)的顶点数及,有向图(网)的信息,出发顶点。 【输出形式】输出出发顶点到有向图(网)其余顶点间的最短路径长度及其路径。 【样例输入】 输入顶点数: 7 输入有向网的信息: 0 4 6 6 32767 32767 32767 32767 0 1 32767 7 32767 32767 32767 32767 0 32767 6 4 32767 32767 32767 2 0 32767 5 32767 32767 32767 32767 32767 0 32767 6 32767 32767 32767 32767 1 0 8 32767 32767 32767 32767 32767 32767 0 输入出发顶点: 0 【样例输出】 从0顶点出发的最短路径如下: 从顶点0到顶点1的路径长度为:4 路径为:0,1 从顶点0到顶点2的路径长度为:5 路径为:0,1,2 从顶点0到顶点3的路径长度为:6 路径为:0,3 从顶点0到顶点4的路径长度为:10 路径为:0,1,2,5,4 从顶点0到顶点5的路径长度为:9 路径为:0,1,2,5 从顶点0到顶点6的路径长度为:16 路径为:0,1,2,5,4,6 使用c语言完成
以下是C语言实现Dijkstra算法解决最短路径问题的代码,注释中有详细解释:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 20 // 图的最大顶点数
#define INFINITY 32767 // 定义无穷大
typedef struct {
int adj; // 记录两个顶点间边的权值
char info[20]; // 存储边的相关信息(可选)
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
int vexs[MAX_VERTEX_NUM]; // 存储顶点信息
AdjMatrix arcs; // 存储边信息
int vexnum, arcnum; // 存储图的顶点数和边数
} MGraph;
// 构造有向网
void CreateMGraph(MGraph *G) {
int i, j, k, w;
printf("请输入有向网的顶点数和边数:\n");
scanf("%d %d", &G->vexnum, &G->arcnum);
printf("请输入有向网的顶点信息:\n");
for (i = 0; i < G->vexnum; i++) {
scanf("%d", &G->vexs[i]);
}
for (i = 0; i < G->vexnum; i++) {
for (j = 0; j < G->vexnum; j++) {
G->arcs[i][j].adj = INFINITY; // 初始化所有边的权值为无穷大
}
}
printf("请输入有向网的边信息(起点 终点 权值):\n");
for (k = 0; k < G->arcnum; k++) {
scanf("%d %d %d", &i, &j, &w);
G->arcs[i][j].adj = w;
}
}
// Dijkstra算法求有向网中某一顶点到其他所有顶点的最短路径
void ShortestPath_DIJ(MGraph G, int v, int dist[], int path[][MAX_VERTEX_NUM]) {
int final[MAX_VERTEX_NUM], i, j, k, min;
// 初始化
for (i = 0; i < G.vexnum; i++) {
final[i] = 0; // 表示顶点i是否已经求得最短路径,0表示未求得,1表示已求得
dist[i] = G.arcs[v][i].adj; // 存储v到i的最短距离
for (j = 0; j < G.vexnum; j++) {
path[i][j] = 0; // 存储v到i最短路径上的顶点序列
}
if (dist[i] < INFINITY) {
path[i][v] = 1;
path[i][i] = 1; // 如果v和i之间有边,则设置path[i][v]和path[i][i]为1
}
}
dist[v] = 0;
final[v] = 1;
// 开始循环,每次求得一个顶点到v的最短路径
for (i = 1; i < G.vexnum; i++) {
min = INFINITY;
// 找到离v最近的顶点k
for (j = 0; j < G.vexnum; j++) {
if (!final[j] && dist[j] < min) {
k = j;
min = dist[j];
}
}
final[k] = 1; // 标记顶点k已经求得最短路径
// 更新dist和path数组
for (j = 0; j < G.vexnum; j++) {
if (!final[j] && min+G.arcs[k][j].adj < dist[j]) {
dist[j] = min+G.arcs[k][j].adj;
// 将k加入v到j的最短路径中
for (int m = 0; m < G.vexnum; m++) {
path[j][m] = path[k][m];
}
path[j][j] = 1;
}
}
}
}
// 输出最短路径
void PrintPath(int dist[], int path[][MAX_VERTEX_NUM], int v) {
int i, j, k;
for (i = 0; i < v; i++) {
printf("从顶点%d到顶点%d的路径长度为:%d\t", v, i, dist[i]);
printf("路径为:%d", v);
j = i;
while (path[i][j] != 1) {
for (k = 0; k < v; k++) {
if (path[i][k] == 1 && G.arcs[k][j].adj < INFINITY) {
printf("->%d", k);
j = k;
break;
}
}
}
printf("->%d\n", i);
}
}
int main() {
MGraph G;
int dist[MAX_VERTEX_NUM]; // 存储最短路径长度
int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 存储最短路径上的顶点序列
printf("构造有向网:\n");
CreateMGraph(&G);
printf("请输入出发顶点:\n");
int v;
scanf("%d", &v);
ShortestPath_DIJ(G, v, dist, path);
printf("从%d顶点出发的最短路径如下:\n", v);
PrintPath(dist, path, G.vexnum);
return 0;
}
```
阅读全文