首页 > 其他分享 >「学习笔记」Floyd 的应用

「学习笔记」Floyd 的应用

时间:2023-04-30 22:33:32浏览次数:36  
标签:right int 短路 笔记 学习 Floyd left 循环 dis

求最短路

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

求最小环

过程

记原图中 \(u,v\) 之间边的边权为 \(val\left(u, v\right)\)。

我们注意到 Floyd 算法有一个性质:在最外层循环到点 \(k\) 时(尚未开始第 \(k\) 次循环),最短路数组 dis 中,\(dis_{u, v}\) 表示的是从 \(u\) 到 \(v\) 且仅经过编号在 \(\left[1, k\right)\) 区间中的点的最短路。
由最小环的定义可知其至少有三个顶点,设其中编号最大的顶点为 \(w\),环上与 \(w\) 相邻两侧的两个点为 \(u,v\),则在最外层循环枚举到 \(k = w\) 时,该环的长度即为 \(dis_{u,v}+val\left(v,w\right)+val\left(w,u\right)\)。
故在循环时对于每个 \(k\) 枚举满足 \(i < k ,j < k\) 的 \(\left(i,j\right)\),更新答案即可。
时间复杂度: \(O_{n^3}\)

int floyd(int n) {
	for (int i = 1; i <= n; ++ i) {
		for (int j = 1; j <= n; ++ j) {
			dis[i][j] = val[i][j];
		} 
	}
	int ans = inf;
	for (int k = 1; k <= n; ++ k) {
		for (int i = 1; i < k; ++ i) {
			for (int j = 1; j < i; ++ j) {
				ans = min(ans, dis[i][j] + val[i][k] + val[k][j]);
			}
		}
		for (int i = 1; i <= n; ++ i) {
			for (int j = 1; j <= n; ++ j) {
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); 
			}
		}
	}
	return ans;
}
for (int k = 1; k <= n; ++ k) {
	for (int i = 1; i < k; ++ i) {
		for (int j = 1; j < i; ++ j) {
			ans = min(ans, dis[i][j] + val[i][k] + val[k][j]);
		}
	}
	for (int i = 1; i <= n; ++ i) {
		for (int j = 1; j <= n; ++ j) {
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); 
		}
	}
}

第一个循环为找最小环,第二个循环为正常更新 dis 数组。

求任意两点的最短路径数

g[x][y] 数组,再求最短路的时候一起维护即可。

for (int k = 1; k <= n; ++ k) {
	for (int i = 1; i <= n; ++ i) {
		for (int j = 1; j <= n; ++ j) {
			if (dis[i][k] + dis[k][j] > dis[i][j]) {
				continue;
			}
			else if (dis[i][k] + dis[k][j] < dis[i][j]) {
				dis[i][j] = dis[i][k] + dis[k][j];
				g[i][j] = g[i][k] * g[k][j];
			}
			else {
				g[i][j] += g[i][k] * g[k][j];
			}
		}
	}
}

传递闭包

即已知一个有向图中任意两点之间是否有连边,要求判断任意两点是否连通。

for (int k = 1; k <= n; ++ k) {
	for (int i = 1; i <= n; ++ i) {
		for (int j = 1; j <= n; ++ j) {
			dis[i][j] |= dis[i][k] & dis[k][j];
		}
	}
}

标签:right,int,短路,笔记,学习,Floyd,left,循环,dis
From: https://www.cnblogs.com/yifan0305/p/17365299.html

相关文章

  • OpenResty学习笔记02:为服务增加waf功能
    一.WAF简介 Web应用防护系统(也称为:网站应用级入侵防御系统。英文:WebApplicationFirewall,简称:WAF)。目前国内的几大云服务商都提供了企业级的WAF产品,且均价格不菲。好消息是,在OpenResty生态中,有一款开源的WAF可供我等学习,开源万岁! 二.开源的WAF 该WAF的作者叫赵......
  • drf学习
    fbv与cbv模式区别:f指的是function,c指的是class路径函数path后面接的不在是veiw中的函数,而是一个继承了View的一个类函数,但是该类函数的返回值是返回一个函数。drf规范:指的是根据前端页面的请求方式来进行操作,如get方式执行读取数据资源,post用于添加数据资源序列化:后端的字典......
  • 树上启发式合并学习笔记
    最近几天了解到一个很神奇的算法——dsuontree,看上去没多快实际上很快,这叫低调。好久不更了,至于反演,5月再更吧,4月的最后一天分享一下dsuontree。顺便闲话一句,4/26是我生日,也是历史二模。重链剖分dsuontree这类dsuontree适用于多次询问,每次询问需要$O(子树大小)......
  • DeepMind:用 GNN 学习通用推理算法
    文|智商掉了一地小孩子才做选择,我的模型全!都!要!近年来,基于深度神经网络的机器学习系统取得了巨大进步,尤其是在以感知为主的任务上。这一领域表现突出的模型通常要在分布中进行泛化,意味着它们的训练和验证集代表了测试输入的预期分布。相比之下,要真正掌握由推理主导的任务,即使是在......
  • 数学学习笔记
    学习了基础的数学,发现我的数学还(fei)算(chang)可(la)以(ji),不多说了,开启美妙的数xiao学之旅吧。进制转换首先是我们熟悉的进制转换,就是n进制转m进制。要把n进制数转化十进制数,再把十进制数转化为m进制数。把n进制数转换为十进制数要先模再除,具体过程就不赘述了,把十进制数转换为m进制数......
  • 2023五一外出学习整理
    DAY1:上午:引入: 对任意两个元素a,b之间关系(a,b)的取值仅为True或者False,可以考虑使用图来抽象。这样我们称一个元素a为一个结点,(a,b)==True则称结点a,b间有连边,否则a,b间没有连边。 问题转化:一张奇数个点的图G,证明存在一个点度数为偶数。转化为更强的问题为:给定一张奇......
  • 学习Git
    欢迎光临LearnGitBranching你对Git感兴趣吗?那么算是来对地方了!“LearningGitBranching”可以说是目前为止最好的教程了,在沙盒里你能执行相应的命令,还能看到每个命令的执行情况;通过一系列刺激的关卡挑战,逐步深入的学习Git的强大功能,在这个过程中你可能还会发现一些有......
  • ts 学习
    1、基础类型leta:(number|String)=newString('123')//String可以是newString/''形式,string则不行2、数组数组特殊需求数组可能是number、string类型数组中有一个元素可有可无数组中前面固定,后面可以随意添加//数组可能是number、string类型letarr......
  • 构建之法阅读笔记2
    《构建之法》这本书有哪些优点?又有哪些不足之处?优点:1、语言生动有趣,采用情景式、对白式的方式对在软件工程相关的学习中重现场景,更好的解决了读者所遇到相类似的问题。   2、注重实践。在大部分时候,大学的计算机专业,理论和实践是分离的,甚至只注重理论,讲一堆概念,定义,然而......
  • iOS学习之UINavigationController…
    1、显示Toolbar 在RootViewController.m的-(void)viewDidLoad方法中添加代码,这样Toobar就显示出来了。1.setToolbarHidden:NOanimated:YES];2、在ToolBar上添加UIBarButtonItem新建几个UIBarButtonItem,然后以数组的形式添加到Toolbar中1.*one=[[UIBarButtonI......