最短路径之floyd算法
简介
原理:用数组的形式存放每对顶点的最短路径长度。
辅助向量:
D[][]用来存放带权长度。
P[][]用来存放前驱顶点
一个测试用例

核心代码
for(k=0;k<G.numVertexes;k++)
{
for(v=0;v<G.numVertexes;v++)
{
for(w=0;w<G.numVertexes;w++)
{
if((*D)[v][w] > (*D)[v][k]+(*D)[k][w])
{
(*D)[v][w]=(*D)[v][k]+(*D)[k][w];
(*P)[v][w]=(*P)[v][k];
}
}
}
}
源代码
/************************
*最短路径之floyd
*时间复杂度:O(n^3)
*优点:形式简单,算法优美。核心代码,三个for循环。
*D[][]用来存放带权长度。
*P[][]用来存放前驱顶点
******************************************************/
#include<stdio.h>
#include<stdlib.h>
#define MAXVER 50 //最大顶点数
#define INFINITY 65535 //65535表示无穷大(邻接表中 权为无穷大表示没有弧)
typedef int Patharc[MAXVER][MAXVER]; // 用于存储最短路径下标的数组
typedef int ShortPathTable[MAXVER][MAXVER]; // 用于存储到各点最短路径的权值和
typedef struct MGraph
{
char vertex[MAXVER] ; //顶点表
int arc[MAXVER][MAXVER] ;//邻接矩阵
int numVertexes, numEdges;//图中当前顶点数和边数
}MGraph;
//建立无向网的邻接矩阵
void CreateGraph(MGraph *G)
{
int i, j,k,w;
//设置顶点个数
printf("请输入图的顶点数,边数:\n");
scanf("%d %d", &G->numVertexes, &G->numEdges);
//getchar();//清空缓冲区(主要是回车)
setbuf(stdin, NULL);//设置输入缓冲区 为空缓冲区
//设置结点存储值
for (i = 0; i < G->numVertexes; i++)
{
printf("\n请输入第%d个顶点存储的值:",i);
scanf("%c", &G->vertex[i]);
// printf("%c",G->vertex[i]);
setbuf(stdin, NULL);//设置输入缓冲区 为空缓冲区(每次输入一个回车,这里会造成 \n字符存在缓冲区)
}
for (i = 0; i < G->numVertexes; i++)
{
for (j = 0; j < G->numVertexes; j++)
{
if(i == j)
{
G->arc[i][j] = 0;
}
else
{
G->arc[i][j] = INFINITY;//初始化邻接矩阵(权为INFINITY无穷大表示没有弧)
}
}
}
for (k = 0; k < G->numEdges; k++)
{
printf("请输入边(vi,vj)的下标i,下标j对应的权w:");
scanf("%d %d %d", &i, &j, &w);
G->arc[i][j] = w;//设置对应的权
G->arc[j][i] = G->arc[i][j];//无向网,对称矩阵
}
}
void ShortestPath_Floyd(MGraph G,Patharc *P,ShortPathTable *D)
{
int v,w,k;//v:行。w:列。k:一次变换。
//初始化D和P
for (v=0;v<G.numVertexes;v++)
{
for(w=0;w<G.numVertexes;w++)
{
(*D)[v][w] = G.arc[v][w];
(*P)[v][w] = w;
}
}
//优美的floyd算法
for(k=0;k<G.numVertexes;k++)
{
for(v=0;v<G.numVertexes;v++)
{
for(w=0;w<G.numVertexes;w++)
{
if((*D)[v][w] > (*D)[v][k]+(*D)[k][w])
{
(*D)[v][w]=(*D)[v][k]+(*D)[k][w];
(*P)[v][w]=(*P)[v][k];
}
}
}
}
}
int main()
{
int v,w;
MGraph G;
CreateGraph(&G);
Patharc P;
ShortPathTable D;
ShortestPath_Floyd(G,&P,&D);
//循环读出D元素
printf("D数组元素为:\n");
for(v=0;v<G.numVertexes;v++)
{
for(w=0;w<G.numVertexes;w++)
{
printf("%d ",D[v][w]);
}
printf("\n");
}
//循环读出P元素
printf("P数组元素为:\n");
for(v=0;v<G.numVertexes;v++)
{
for(w=0;w<G.numVertexes;w++)
{
printf("%d ",P[v][w]);
}
printf("\n");
}
system("pause");
return 0;
}
测试结果

本文介绍了图论中的弗洛伊德算法,用于求解所有顶点对之间的最短路径。通过使用三重循环遍历邻接矩阵,动态更新最短路径。并提供了一个C++实现的示例,包括创建无向网的邻接矩阵及最短路径计算。该算法具有简洁和高效的特点,时间复杂度为O(n^3)。

624

被折叠的 条评论
为什么被折叠?



