文字描述

  求每一对顶点间的最短路径,可以每次以一个顶点为源点,重复执行迪杰斯特拉算法n次。这样,便可求得每一对顶点之间的最短路径。总的执行时间为n^3。但是还有另外一种求每一对顶点间最短路径的方法,就是弗洛伊德(Floyd)算法,它的时间复杂度也为n^3,但是形式上更简单,其基本思想如下:

  

  如果无法理解上面的文字的话,建议看下代码实现部分,可以更容易理解。

示意图

 

算法分析

时间复杂度为n^3

代码实现

 //
// Created by lady on 19-1-6.
// #include <stdlib.h>
#include <stdio.h>
#include <string.h> #define INFINITY 100000 //最大值
#define MAX_VERTEX_NUM 20 //最大顶点数 typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网}
typedef struct ArcCell{
int weight; //该弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM], PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct VertexType{
char data[];
}VertexType;
typedef struct{
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum, arcnum; //图的当前顶点数和弧数
GraphKind kind; //图的种类标志
}MGraph; /*
* 根据顶点信息, 返回该顶点在图中的位置, 如果返回-1表示顶点不存在
*/
static int LocateVex(MGraph *G, char data[])
{
int i = ;
for(i=; i<G->vexnum; i++){
if(!strncmp(G->vexs[i].data, data, strlen(G->vexs[i].data))){
return i;
}
}
return -;
} /*
* 用邻接矩阵作为存储结构,创建有向网
*/
static int CreateGraphDN(MGraph *G)
{
printf("用邻接矩阵创建有向网,输入顶点数,弧数:");
G->kind = DN;
scanf("%d,%d", &G->vexnum, &G->arcnum);
if(G->vexnum > MAX_VERTEX_NUM){
printf("错误:顶点数不能超过%d!!\n", MAX_VERTEX_NUM);
return -;
}
int i = , j = , k = ;
char v1[] = {}, v2[]={}, info[] = {};
char tmp[] = {};
for(i=; i<G->vexnum; i++){
printf("输入第%d个顶点: ", i);
memset(G->vexs[i].data, , sizeof(G->vexs[].data));
scanf("%s", G->vexs[i].data);
for(j=; j<G->vexnum; j++){
G->arcs[i][j].weight = INFINITY;
}
G->arcs[i][i].weight = ;
}
for(k=; k<G->arcnum; k++){
printf("输入第%d条弧(顶点1, 顶点2, 权值): ", k);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%[^','],%[^','],%s[^\\n]", v1, v2, info);
i = LocateVex(G, v1);
j = LocateVex(G, v2);
if(i< || j< || (!atoi(info))){
printf("错误:顶点%s或者%s不存在, 或者权值信息%s不对!\n", v1, v2, info);
return -;
}
G->arcs[i][j].weight = atoi(info);
}
return ;
} static void printMatrix(int vexnum, VertexType vexs[], int (*arcs)[MAX_VERTEX_NUM])
{
int i = , j = ;
printf("\t");
for(i=; i<vexnum; i++){
printf("%s\t", vexs[i].data);
}
printf("\n");
for(i=; i<vexnum; i++){
printf("%s\t", vexs[i].data);
for(j=; j<vexnum; j++){
if(arcs[i][j] == INFINITY){
printf("INF\t");
}else{
printf("%d\t", arcs[i][j]);
}
}
printf("\n");
}
return ;
}
static void printArchs(int vexnum, VertexType vexs[], AdjMatrix arcs)
{
int i = , j = ;
printf("\t");
for(i=; i<vexnum; i++){
printf("%s\t", vexs[i].data);
}
printf("\n");
for(i=; i<vexnum; i++){
printf("%s\t", vexs[i].data);
for(j=; j<vexnum; j++){
if(arcs[i][j].weight == INFINITY){
printf("INF\t");
}else{
printf("%d\t", arcs[i][j].weight);
}
}
printf("\n");
}
return ;
} /*
* 用Floyd算法求有向图G中各顶点v和w之间的最短路径P[v][w]及其
* 带权长度D[v][w]。若P[v][w][u]为1, 则u为从v到w当前求得最短路径上的顶点。
*/
void ShortestPath_Floyd(MGraph *G)
{
int u=, v=, w=;
int i=, j=;
int P[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//各对结点之间初始已知路径和距离
for(v=; v<G->vexnum; v++){
for(w=; w<G->vexnum; w++){
D[v][w] = G->arcs[v][w].weight;
for(u=; u<G->vexnum; u++){
P[v][w][u] = ;
}
//从v到w有直接路径
if(D[v][w] < INFINITY){
P[v][w][v] = ;
P[v][w][w] = ;
}
}
} for(u=; u<G->vexnum; u++){
for(v=; v<G->vexnum; v++){
for(w=; w<G->vexnum; w++){
if( D[v][u]+D[u][w] < D[v][w]){
//从v经u到w的一条路径更短。
D[v][w] = D[v][u] + D[u][w];
for(i=; i<G->vexnum; i++){
P[v][w][i] = (P[v][u][i] || P[u][w][i]) ? : ;
}
}
}
}
} printf("\n打印各个顶点间的最短路径的权值:\n");
printMatrix(G->vexnum, G->vexs, D); printf("\n打印各个顶点间的最短路径的中间结点:\n");
for(u=; u<G->vexnum; u++){
for(v=; v<G->vexnum; v++){
printf("minpath(%d,%s<->%d,%s):", u, G->vexs[u].data, v, G->vexs[v].data);
for(w=; w<G->vexnum; w++){
if(P[u][v][w] && (u!=v)){
printf("%s\t", G->vexs[w].data);
}
}
printf("\n");
}
} return ;
} int main(int argc, int *argv[])
{
//以邻接矩阵为存储结构创建有向网
MGraph G;
if(CreateGraphDN(&G) < ){
return -;
}
printf("\n打印该图中的信息:\n");
printArchs(G.vexnum, G.vexs, G.arcs);
//Floyd弗洛依德算法求多源最短路径
ShortestPath_Floyd(&G);
}

弗洛依德算法(Floyd)求多源最短路径

代码运行

/home/lady/CLionProjects/untitled/cmake-build-debug/untitled
用邻接矩阵创建有向网,输入顶点数,弧数:,
输入第0个顶点: A
输入第1个顶点: B
输入第2个顶点: C
输入第0条弧(顶点1, 顶点2, 权值): A,B,
输入第1条弧(顶点1, 顶点2, 权值): B,A,
输入第2条弧(顶点1, 顶点2, 权值): A,C,
输入第3条弧(顶点1, 顶点2, 权值): C,A,
输入第4条弧(顶点1, 顶点2, 权值): B,C, 打印该图中的信息:
A B C
A
B
C INF 打印各个顶点间的最短路径的权值:
A B C
A
B
C 打印各个顶点间的最短路径的中间结点:
minpath(,A<->,A):
minpath(,A<->,B):A B
minpath(,A<->,C):A B C
minpath(,B<->,A):A B C
minpath(,B<->,B):
minpath(,B<->,C):B C
minpath(,C<->,A):A C
minpath(,C<->,B):A B C
minpath(,C<->,C): Process finished with exit code

图->最短路径->多源最短路径(弗洛伊德算法Floyd)的更多相关文章

  1. 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)

    文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...

  2. 最短路径问题---Floyed(弗洛伊德算法),dijkstra算法,SPFA算法

    在NOIP比赛中,如果出图论题最短路径应该是个常考点. 求解最短路径常用的算法有:Floyed算法(O(n^3)的暴力算法,在比赛中大概能过三十分) dijkstra算法 (堆优化之后是O(MlogE ...

  3. dijkstra 两点的最短路径 单源 最短路径

    思路以dist数组 来扩充  路径的访问,不断的刷新dist数组 设置一个顶点的集合s,并不断地扩充这个集合,一个顶点属于集合s当且仅当从源点到该点的路径已求出.开始时s中仅有源点,并且调整非s中点的 ...

  4. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  5. Dijkstra算法——单源最短路径问题

    学习一个点到其余各个顶点的最短路径--单源最短路径 Dijkstra算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向 ...

  6. 弗洛伊德算法(Floyd算法)

    原博来自http://www.cnblogs.com/skywang12345/ 弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的 ...

  7. SPFA解决单源最短路径

    SPFA(Shortest Path Faster Algorithm): 一:基本算法 在求解单源最短路径的时候,最经典的是 Dijkstra 算法,但是这个算法对于含有负权的图就无能为力了,而 B ...

  8. 经典问题----最短路径(Floyd弗洛伊德算法)(HDU2066)

    问题简介: 给定T条路,S个起点,D个终点,求最短的起点到终点的距离. 思路简介: 弗洛伊德算法即先以a作为中转点,再以a.b作为中转点,直到所有的点都做过中转点,求得所有点到其他点的最短路径,Flo ...

  9. 多源最短路径算法—Floyd算法

    前言 在图论中,在寻路最短路径中除了Dijkstra算法以外,还有Floyd算法也是非常经典,然而两种算法还是有区别的,Floyd主要计算多源最短路径. 在单源正权值最短路径,我们会用Dijkstra ...

随机推荐

  1. 基于R语言的ARIMA模型

    A IMA模型是一种著名的时间序列预测方法,主要是指将非平稳时间序列转化为平稳时间序列,然后将因变量仅对它的滞后值以及随机误差项的现值和滞后值进行回归所建立的模型.ARIMA模型根据原序列是否平稳以及 ...

  2. Effective Java 第三版笔记(目录)

    <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时 ...

  3. IntelliJ IDEA配置

    1.取消idea默认打开工程: 2.导出,导入配置. 导出和导入配置好处:对IDEA配置好后导出配置,方便以后重装电脑或者重装IDEA后可以导入之前配置好的配置.避免重复配置 导出配置:File Ex ...

  4. 从yield 到yield from再到python协程

    yield 关键字 def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b yield 是在:PEP 255 -- Simple Generator ...

  5. UBANTU zongjie

    1.fatal error: openssl/aes.h: No such file or directory 要在Debian.Ubuntu或者其他衍生版上安装OpenSSL: $ sudo apt ...

  6. 科普知识普及 - 桥接VS中继

    首先要说明一个很多人理解的误区,中继比桥接好用,真的是这么回事么? 答案是否定的. 我们在说桥接和中继的时候我们要先了解,桥接和中继的工作原理.还有一个问题,估计很多人都想不明白:为什么中继搜到的信号 ...

  7. RSA加密算法详解(二)

    研究RSA 不知为何,这几天突然有些心烦.望苍茫大地,凭添几分忧伤,可能是下雨的缘故.本篇主要想详细介绍RSA加密算法的原理,经常听别人说,这里是自己想搞清楚,弄明白.首先介绍了基本的数学原理,然后给 ...

  8. Linux解压缩命令tar

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...

  9. Ajax+Python flask实现上传文件功能

    HTML: <div > <input type="file" name="FileUpload" id="FileUpload&q ...

  10. iOS电量获取

    一.Ios获取方法 Instrument电量工具获取 操作步骤: a) 手机不能连接数据线,kill掉后台所有app进程 b) 点击设置,选择开发,点击Logging,开启Energy,点击Start ...