图论最短路 之 弗洛伊德Floyd(详细分析)

什么是Floyd算法

佛洛伊德是最简单的最短路径算法,可以计算图中任意两点间的最短路径。时间复杂度为O(N3),适用于出现负边权的情况。

怎么用代码实现?

算法描述:
( a )初始化:点u、v如果有边相连,则dis[u][v]=w[u][v]
如果不相连,则dis[u][v]=0x3f
( b )模板:

for(k=1;k<=n;k++){
   
	for(i=1;i<=n;i++){
   
		for(j=1;j<=n;j++){
   
			if(dis[i][j]>dis[i][k]+dis[k][j])
			  	dis[i][j]=dis[i][k]+dis[k][j];
		}
	}
}
	

( c )算法结束:dis[i][j]得出的就是任意起点i到任意终点j的最短路径。

疑问:为什么枚举中间点的循环k要放在最外层?

可以从一定不经过k点与一定经过k点的三维数组比较中推导出来



使用Floyd输出最短路径序列

Floyd算法输出路径也是采用记录前驱点的方式。因为floyd是计算任意两点间最短路径的算法,dis[i][j]记录从i到j的最短路径值。故我们定义pre[i][j]为一个二维数组,记录从i到j的最短路径中,j的前驱点是哪一个。递归还原路径。

初始化pre[N][N]为0,输入相连边时,重置相连边尾结点的前驱
若有无向边:pre[a][b]=a; pre[b][a]=b;

更新若floyd最短路有更新,那么pre[i][j]=pre[k][j];(这能不能直接赋值k的值?)

递归输出指两点s,e的最短路,先输出起点s,再将终点e放入递归,输出s+1~e的所有点。

void print(int x){
   
	if(pre[s][x]==0) return;
	print(pre[s][x]);
	printf(->%d”,x);
}


例题板题


① 最短路径问题

平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值