floyd算法

Floyd算法实验报告

大城市里の小女人 提交于 2020-03-10 22:14:11
问题[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)] 弗洛伊德算法定义了两个二维矩阵: 矩阵D记录顶点间的最小路径 例如D[0][3]= 10,说明顶点0 到 3 的最短路径为10; 矩阵P记录顶点间最小路径中的中转点 例如P[0][3]= 1 说明,0 到 3的最短路径轨迹为:0 -> 1 -> 3。 解析[问题的理解和推导,可用电子版直接在此编写,也可用纸笔推导,拍照嵌入本文档] 设计[核心伪代码] //这里是弗洛伊德算法的核心部分 //k为中间点 for(k = 0; k < G.vexnum; k++){ //v为起点 for(v = 0 ; v < G.vexnum; v++){ //w为终点 for(w =0; w < G.vexnum; 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];//更新最小路径中间顶点 } } } } 分析[算法复杂度推导]三重循环,算法复杂度为O(N^3) 源码[github源码地址] https://github.com/hackkkkkk/calculate 来源: CSDN 作者: ice___cream 链接: https://blog.csdn.net/ice_

深入理解floyd算法

风格不统一 提交于 2020-03-06 16:40:58
先上floyd算法的代码,本质上是动态规划问题 本质就是DP含有动态规划的思想,满足重叠子问题和最优子结构 dis[k][i][j]=min(dis[k-1][i][j],dis[k-1][i][k]+dis[k-1][k][j]); 我们可以发现他其实是由前k-1的状态来推出第k个点的状态之后你就会发现f[k]只与f[k-1]有关 然后我们可以根据这个性质解决很多问题 for ( k = 1 ; k <= n ; k ++ ) { for ( i = 1 ; i <= n ; i ++ ) { for ( j = 1 ; j <= n ; j ++ ) { if ( dis [ i ] [ k ] + dis [ k ] [ j ] < dis [ i ] [ j ] ) { dis [ i ] [ j ] = dis [ i ] [ k ] + dis [ k ] [ j ] ; } } } } 这个经典代码的难点在于理解为什么k的循环在外面,这里附上一波知乎的高赞解释 可能部分大佬看到这段抽象的解释之后已经豁然开朗,如果还有部分大佬没有看懂的话,本菜鸡尝试用通俗的语言来翻译一下 这里给出一张简单的有向图 1->5,5->6,6->3的距离均为1,如果按照k值在最内部进行循环的话 dist[1][3]的距离无法更新, 因为dist[1][3] = dist[1][6] +

最短路之Floyd算法

╄→гoц情女王★ 提交于 2020-03-04 14:10:38
问题 已知一张有向图,求出每个点到其他点的最短路径,也就是多源最短路径的问题。 解析 Floyd算法的本质是一种动态规划的思想,它的转移方程为:mp[i,j]=min(mp[i,k]+mp[k,j],mp[i,j]),其中mp[i,j]代表从i点到j点的最短距离,所以可以枚举i点和j点,更新每个i到j的最短距离再枚举k,但是这样枚举计算mp[i,j],因为不能确定枚举的所有到k点为最短路径,一旦确定后,之后不会修改,所以应该先枚举k,再枚举i,j,这样就实现了Floyd算法。 从任意节点i到任意节点j的最短路径不外乎2种可能: 1)直接从节点i到节点j。 2)从节点i经过若干个节点k到节点j。 所以,我们假设mp(i,j)为节点i到节点j的最短路径的距离,对于每一个节点k,我们检查mp(i,k)+mp(k,j)<mp(i,j)是否成立,如果成立,证明从节点i到节点k再到节点j的路径比节点i直接到节点j的路径短,我们便设置mp(i,j)=mp(i,k)+mp(k,j),这样一来,当我们遍历完所有节点k,mp(i,j)中记录的便是节点i到节点j的最短路径的距离。 初始的距离矩阵: 0 2 6 4 inf 0 3 inf 7 inf 0 1 5 inf 12 0 本题的最短路径矩阵: 0 2 5 4 9 0 3 4 6 8 0 1 5 7 10 0 设计 枚举顶点k ∈ [ 1 , n

Floyd算法模板

梦想与她 提交于 2020-02-23 01:21:27
hdu2544 # include <cstdio> using namespace std ; const int N = 105 ; const int INF = 1e5 + 5 ; int n , m , u , v , c , map [ N ] [ N ] ; void floyd ( ) { for ( int k = 1 ; k <= n ; k ++ ) { for ( int i = 1 ; i <= n ; i ++ ) { if ( map [ i ] [ k ] != INF ) { for ( int j = 1 ; j <= n ; j ++ ) { if ( map [ i ] [ j ] > map [ i ] [ k ] + map [ k ] [ j ] ) { map [ i ] [ j ] = map [ i ] [ k ] + map [ k ] [ j ] ; } } } } } printf ( "%d\n" , map [ 1 ] [ n ] ) ; } int main ( ) { while ( scanf ( "%d%d" , & n , & m ) , n ) { for ( int i = 1 ; i <= n ; i ++ ) { for ( int j = 1 ; j <= n ; j ++ ) { map [ i ]

HDOJ Floyd算法

回眸只為那壹抹淺笑 提交于 2020-01-30 17:04:44
Target Floyd算法 HDOJ 2544 Point 复习Floyd算法,详细可见: 数据结构与算法基础–第11周08–6.6图的应用8–6.6.2最短路径3–Floyd算法 . 注意无穷大: 为何程序员喜欢将INF设置为0x3f3f3f3f . Code #include < iostream > #define inf 0x3f3f3f3f using namespace std ; int map [ 111 ] [ 111 ] ; //较大数组写成全局变量 int main ( ) { int n , m , i , j , k ; while ( cin >> n >> m && ( n || m ) ) { //initialize for ( i = 1 ; i <= n ; ++ i ) for ( j = 1 ; j <= n ; ++ j ) map [ i ] [ j ] = inf ; //input for ( i = 1 ; i <= m ; ++ i ) { int a , b , c ; cin >> a >> b >> c ; map [ a ] [ b ] = c ; map [ b ] [ a ] = c ; } for ( k = 1 ; k <= n ; ++ k ) { for ( i = 1 ; i <= n ; ++ i )

200117(最短路径的Floyd算法)

你离开我真会死。 提交于 2020-01-24 01:50:39
Floyd算法是一个经典的动态规划算法。简单地说,首先我们的目标是寻找从顶点 i 到顶点 j 的最短路径。 从任意顶点i到任意顶点j的最短路径不外乎2种可能,一是直接从 i 到 j ,二是从 i 经过若干个中间顶点到 j 。所以,我们假设D(i,j)为顶点 i 到顶点 j 的最短路径的距离,对于每一个顶点 k,我们检查D(i,k) + D(k,j) < D(i,j)是否成立,如果成立,证明从 i 到 k 再到 j 的路径比 i 直接到 j 的路径短,我们便设置D(i,j) = D(i,k) + D(k,j),这样一来,当我们遍历完所有顶点 k,D(i,j)中记录的便是 i 到 j 的最短路径的距离。 算法过程: 1)首先把初始化距离数组D为图的邻接矩阵arc,路径数组P初始化为P[i][j]=j(初始化时由于 i 是直接到 j 的,所以 i 的后继结点就是 j ); 2)对于每一对顶点 i 和 j,遍历所有顶点,看看是否存在一个顶点 k 使得从 i 到 k 再加上 k 到 j 比直接从 i 到 j 的路径更短。如果是就更新D[i][j]。 递推关系式为: 如果 D[i][k]+D[k][j] < D[i][j] 则D[i][j] = D[i][k]+D[k][j] 注意!!!:仔细思考递推关系式会发现由于D[i][i]始终为0, 所以 i 、j 、k

Floyd算法

谁都会走 提交于 2020-01-19 15:28:29
传送门: Dijkstra Bellman-Ford SPFA Floyd 1. 算法思想: 定义一个n阶方阵序列:A (-1) A (0) A (1) A (2) ....... A (n-1) A (-1) [i][j]表示顶点Vi到顶点Vj的直接边的长度,A (-1) 就是邻接矩阵Edge[n][n] A (0) [i][j]表示顶点Vi到顶点Vj,中间顶点(如果有,则)是V0的最短路径长度 A (1) [i][j]表示顶点Vi到顶点Vj,中间顶点序号不大于1的最短路径长度 A (2) [i][j]表示顶点Vi到顶点Vj,中间顶点序号不大于2的最短路径长度 A (n-1) [i][j]表示顶点Vi到顶点Vj最短路径长度 允许带有负权值的边,但不能有负权值回路。 2.代码实现 输入: 4 8 0 1 1 0 3 4 1 2 9 1 3 2 2 0 3 2 1 5 2 3 8 3 2 6 输出: 0->1 1 0->1 0->2 9 0->1->3->2 0->3 3 0->1->3 1->0 11 1->3->2->0 1->2 8 1->3->2 1->3 2 1->3 2->0 3 2->0 2->1 4 2->0->1 2->3 6 2->0->1->3 3->0 9 3->2->0 3->1 10 3->2->0->1 3->2 6 3->2 递推式a[i][j] =

Floyd算法(求最短路)

删除回忆录丶 提交于 2020-01-19 15:27:20
Floyd算法 摘自:百度百科:http://baike.baidu.com/view/14495.htm 百科名片 弗洛伊德算法 Floyd 算法 又称为 弗洛伊德算法 ,插点法,是一种用于寻找给定的 加权图 中顶点间 最短路径 的算法。该 算法 名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授 罗伯特·弗洛伊德 命名。 核心思路 通过一个图的权值 矩阵 求出它的每两点间的 最短路径 矩阵 。 从图的带权 邻接矩阵 A=[a(i,j)] n×n开始, 递归 地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出 矩阵 D(n)。 矩阵 D(n)的i行j列元素便是i号顶点到j号顶点的 最短路径 长度,称D(n)为图的 距离矩阵 ,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。 采用的是(松弛技术),对在i和j之间的所有其他点进行一次松弛。所以 时间复杂度 为O(n^3); 其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]} map[i,j]表示i到j的最短距离 K是穷举 i,j的 断点 map[n,n]初值应该为0,或者按照题目意思来做。 当然,如果这条路没有通的话,还必须特殊处理,比如没有map

最短路径问题-Floyd算法

醉酒当歌 提交于 2020-01-19 15:25:35
概念 最短路径也是图的一个应用,即寻找图中某两个顶点的最短路径长度。 实际应用:例如确定某两个城市间的坐火车最短行车路线长度等。 Floyd algorithm 中文名就是弗洛伊德算法。 算法思路:用邻接矩阵来存储图的结构,edge[i][j]表示从结点i到结点j的最短路径长度,那么该如何计算edge[i][j]呢?首先我们可以假设当前的edge[i][j]不是最短的路径长度,必须经过k结点,比较edge[i][i]与edge[i][k]+edge[k][j]的大小(其中k的取值为所有点的编号),如果前者小,则表明i到j的最短路径为当前的edge[i][j];如果后者小,那么就需要修改当前的edge[i][j],使得edge[i][i]=edge[i][k]+edge[k][j]。 ok,下面用代码表示一下: for (int k = 1; k <= n; k++) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (edge[i][k] == MAX || edge[k][j] == MAX) continue; if (edge[i][j] == MAX || edge[i][k] + edge[k][j] < edge[i][j]) edge[i][j] = edge[i][k] + edge

Floyd算法(弗洛伊德算法)

我们两清 提交于 2020-01-19 15:24:30
算法描述:   Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。 核心思路:通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。 算法过程:   把图用邻接距阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个距阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。 在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3