Floyd为什么k循环要在最外层

2023-10-20 03:08
文章标签 循环 floyd 外层

本文主要是介绍Floyd为什么k循环要在最外层,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

适用情况:
该算法不能解决带有“负权回路”(或者叫“负权环”)的图

时间复杂度为 o(n^3)

参考博客:
作者:Yuliang.wang
地址:https://www.cnblogs.com/wangyuliang/p/9216365.html

代码

#include <bits/stdc++.h>
using namespace std;
int f[1020][1020];
int main(){int n,m,s,t;int x,y,z;cin >> n >> m >> s >> t;memset(f,0x3f,sizeof(f));for(int i = 0;i < m;i++){cin >> x >> y >> z;f[x][y] = min(f[x][y],z);//可能每对点有多条边f[y][x] = min(f[y][x],z);}for(int i = 1;i <= n;i++){f[i][i] = 0;}for(int k = 1;k <= n;k++){for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){//if(i != j && j != k && i!= k)f[i][j] = min(f[i][j],f[i][k] + f[k][j]);//f[i][k]+f[k][j]越界,所以f[][]不能赋值为127}}}if(f[s][t] >= 0x3f3f3f){cout << -1 << endl;}else cout << f[s][t] << endl;return 0;
}

注意
循环k要在最外层

如果写成内层,例如像下面一样是不行的

for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){for(int k = 1;k <= n;k++){f[i][j] = min(f[i][j],f[i][k] + f[k][j]);}	}}

因为floyd本质目的是对于每个点对i-j的距离可以被其它点优化,而且可以被多个点共同优化,如果循环k在内层,那么i,j每次只能得到一个点的优化。

如下列情况

如图
在这里插入图片描述

注意:初始时,两点间的路径还没被优化,所以只有两点直接有边才算有路径。

当算法跑到 i= 1,j = 2; k = 4;时

k循环在内部:
点1-2的路径只能通过单一的点,要么3(3-2路径还没被优化,所以没有路),要么4(1-4路径还没被优化,所以没有路)来优化路径,没有考虑到同时使用3,4来优化,于本意相反

k循环在最外部:
先用 k = 3优化 使得i->j->k :1->3->4 这样点对1-4就有路径了
k = 4 时 就可以得到 1->4->2; (1->4已经通过3优化了,相当于3也优化了1->2),所以点对1-2的路径可以被3,4共同优化

算法思想:
folyd利用了动态规划的思想,学过背包问题的,不难发现,它和01背包很像,外围那个K循环就相当于物品,所以对每个点对i-j的路径,都可以选择1个、2个、……k个点对路径进行优化

这篇关于Floyd为什么k循环要在最外层的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/244192

相关文章

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

Python判断for循环最后一次的6种方法

《Python判断for循环最后一次的6种方法》在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态... 目录1.使用enuhttp://www.chinasem.cnmerate()和len()来判断for

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在

JAVA中while循环的使用与注意事项

《JAVA中while循环的使用与注意事项》:本文主要介绍while循环在编程中的应用,包括其基本结构、语句示例、适用场景以及注意事项,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录while循环1. 什么是while循环2. while循环的语句3.while循环的适用场景以及优势4. 注意

Python中的异步:async 和 await以及操作中的事件循环、回调和异常

《Python中的异步:async和await以及操作中的事件循环、回调和异常》在现代编程中,异步操作在处理I/O密集型任务时,可以显著提高程序的性能和响应速度,Python提供了asyn... 目录引言什么是异步操作?python 中的异步编程基础async 和 await 关键字asyncio 模块理论

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

uva 10099(floyd变式)

题意: 有一个导游要带着一群旅客从一个城市到达另一个城市,每个城市之间有最大的旅客流量限制。 问最少几趟能将这些旅客从一个城市搞到另一个城市。 解析: 用floyd找出最小流量中的最大边,然后次数就是   ceil(总人数 / 最大承载量 - 1),-1的意思是导游每次也要在车上。 ps.老司机哭晕在厕所 代码: #include <iostream>#includ

uva 10048(floyd变式)

题意: 求两个点之间经过的路径中最大噪声最小的值。 解析: floyd的变式,每次取g[i][k] g[k][j]中的大边与当前边g[i][j]比较,取小。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#includ

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大