算法学习笔记(5) 传递闭包

本文属于「算法学习」系列文章之一。之前的【数据结构和算法设计】系列着重于基础的数据结构和算法设计课程的学习,与之不同的是,这一系列主要用来记录对大学课程范围之外的高级算法学习、优化与使用的过程,同时也将归纳总结出简洁明了的算法模板,以便记忆和运用。在本系列学习文章中,为了透彻讲解算法和代码,本人参考了诸多博客、教程、文档、书籍等资料,由于精力有限,恕不能一一列出。

为了方便在PC上运行调试、分享代码,我还建立了相关的仓库:https://github.com/memcpy0/Algorithm-Templates。在这一仓库中,你可以看到算法文章、模板代码、应用题目等等。由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏算法学习系列文章目录一文以作备忘。


1. 传递闭包含义和实现

在离散数学的图论专题中,一般都会学到「传递闭包」这种算法。从集合论角度来看,传递闭包是在集合 X X X 上求包含二元关系 R R R 的最小传递关系;从图论角度来看,如果原关系图上有 u u u v v v路径,则传递闭包的关系图上就有从 u u u v v v——实际上就是确定每个点是否能够到达其他每个点

具体来说,修改一下全源最短路Floyd算法即可。依次判断:仅经过顶点 1 能不能从 i 到达 j ,仅经过顶点 1, 2 能不能从 i 到达 j ……,仅经过顶点 1, 2, ..., n 能不能从 i 到达 j ,能够到达则赋值为 1 ,表示 i 可达 j 。设 M 为关系图的关系矩阵,求其传递闭包的具体代码如下,时间复杂度为 O ( n 3 ) O(n^3) O(n3)

for (int k = 1; k <= n; ++k) 
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if (M[i][k] && M[k][j])
				M[i][j] = 1;

或者说,使用Floyd-Warshall算法——就是上述代码的变形:

for (int k = 1; k <= n; ++k) 
	for (int i = 1; i <= n; ++i)
		if (M[i][k])
			for (int j = 1; j <= n; ++j)
				M[i][j] = M[i][j] || M[k][j];

2. 各大OJ题目应用

题目链接题解文章
POJ 1975 Median Weight BeadPOJ 1975 Median Weight Bead【传递闭包】
POJ 3660 Cow ContestPOJ 3660 Cow Contest【传递闭包】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

memcpy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值