Peter算法小课堂—并查集

这篇具有很好参考价值的文章主要介绍了Peter算法小课堂—并查集。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我们先来看太戈编程467题 攀亲戚

题目描述:

最近你发现自己和古代一个皇帝长得很像:都有两个鼻子一个眼睛,你想知道这皇帝是不是你的远方亲戚,你是不是皇亲国戚。目前你能掌握的信息有m条,关于n个人:第i条信息包含两个人的编号ai,bi,表示ai和bi是亲戚。你的编号是0,皇帝的编号是1,最大编号为n-1,请问能否通过信息推理出你和皇帝是不是亲戚? 备注:众所周知,亲戚关系具有传递性。

连通块问题三大杀手:1.DFS 2.BFS 3.并查集

我们先定义一个id[]数组,表示i号节点的老爸(不是祖宗)。那么……想象一下,把样例构建成一幅图,怎么做呢(想象着想象着就睡着了)?哈哈,我们将无向边化作有向边即可,什么意思呢,就是呢,这个,啊这,嗯,差不多。回到题目,我们发现,皇帝有两个鼻子一个眼睛。

Peter算法小课堂—并查集,图论,建模,算法,深度优先,图论

从这个变成……

Peter算法小课堂—并查集,图论,建模,算法,深度优先,图论

按连接关系写完id[]。 即看到一条,就在图上加一条边。

那如何判断7和8是否连通呢?其实,我们用root()函数表示一个节点的祖宗,判断root(7)==root(8)就行了。

我们人手动加一条边好弄啊,但是计算机不认识啊,咋办嘞。

Peter算法小课堂—并查集,图论,建模,算法,深度优先,图论

我们能不能直接7到8连条线呢?那这时我们发现8的老爸有两个耶,id[8]只能存一个。简单来说就是,不能去修改已经有父亲的点的id。那能不能让1认7做它父亲捏?1又没有父亲。可以是可以,但是……你想想找8的祖宗得走多远呢,换句话说,这棵树的深度太高。正确答案是让1认0做它老爸。所以,unite()函数要调用两次root()。

Peter算法小课堂—并查集,图论,建模,算法,深度优先,图论

所以说main()函数如下

int main(){
	cin>>m>>n;
	for(ll i=0;i<n;i++) id[i]=i;
	while(m--){
		cin>>x>>y;
		unite(x,y);
	}
	if(root(1)==root(0)) cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
}

 root()和unite()如下

ll root(ll x){
	if(id[x]==x) return x;
	else return root(id[x]);
}
void unite(ll x,ll y){
	ll rx=root(x),ry=root(y);
	id(rx)=ry;
}

此时看到代码的你立马复制黏贴。殊不知,没有AC。为什么呢?原来可以优化。

Peter算法小课堂—并查集,图论,建模,算法,深度优先,图论

这叫“路径压缩”。那优化完的代码长什么样呢?

ll root(ll x){
	return id[x]==x?x:id[x]=root(id[x]);
}

 就这一处变化。那有的小彭友说我用BFS、DFS那不香吗?为什么我们用并查集,因为unite()、root()函数时间复杂度为O(1)!总复杂度O(m+n)!总空间复杂度O(n)!

并查集可视化网址:并查集 (Union-Find Disjoint Sets, 简称UFDS) - VisuAlgo文章来源地址https://www.toymoban.com/news/detail-800822.html

到了这里,关于Peter算法小课堂—并查集的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图论基础知识 并查集/例题

    学习记录自代码随想录 并查集常用来解决连通性问题。 判断两个元素是否在同一个集合里的时候,要想到用并查集。 并查集主要有两个功能: 1.将两个元素添加到一个集合中; 2.判断两个元素在不在同一个集合。 例题:20240410 Huawei机考

    2024年04月25日
    浏览(35)
  • 图论02-并查集的实现(Java)

    2.并查集理论基础 并查集的作用 并查集的实现 Java代码实现 路径压缩 优化后完整代码

    2024年03月25日
    浏览(47)
  • 图论:并查集的合并、判断和求节点

     所谓并查集就是可以画图理解 假如说我们想要构建一个树(也是图),要求1-2,2-4,1-3 在构另一个树,要求5-6,6-7,5-8 1是2的头结点,2是4的头结点,以此类推 下面要求去将5连接到1上,就是我下面要讲的,其实上面的子节点的连接也是如此的。 简单并查集例题: 一共有 n 个数

    2024年01月18日
    浏览(37)
  • Peter算法小课堂—贪心算法

    课前思考:贪心是什么?贪心如何“贪”? 课前小视频:什么是贪心算法 - 知乎 (zhihu.com) 贪心是一种寻找最优解问题的常用方法。 贪心一般将求解过程分拆成若干个步骤,自顶向下,解决问题 题目描述: 你有一台抓娃娃机器,玩法有点特别:机器会随机给你一排N个娃娃(

    2024年02月05日
    浏览(38)
  • 代码随想录图论并查集 第七天 | 685.冗余连接II

    代码随想录图论并查集 第七天 | 685.冗余连接II 一、685.冗余连接II 题目链接:https://leetcode.cn/problems/redundant-connection-ii/ 思路:684.冗余连接中是连通且无环的无向图可直接使用并查集模板,如果想判断集合中是否有环,且那条边构成环,只需要每次加入并查集之前先判断一下是

    2024年02月06日
    浏览(54)
  • Peter算法小课堂—贪心与二分

    题目描述: 有n辆车大甩卖,第i辆车售价a[i]元。有m个人带着现金来申请购买,第i个到现场的人带的现金为b[i]元,只能买价格不超过其现金额的车子。你是大卖场总经理,希望将车和买家尽量多地进行一对一配对,请问最多卖出多少辆车? 贪心法模板: 比如说:每次挑最便

    2024年02月02日
    浏览(40)
  • Peter算法小课堂—树的应用

    开篇先给大家讲个东西,叫vector,有老师称之为“向量”,当然与数学中的向量不一样啊,所以我要称之为“长度可变的数组” 头文件:#include vector 用法:vectorint d; 尾部增加元素:d.push_back(……); 元素个数:d.size() 数组方括号操作:d[i] 尾部删除元素:d.pop_back(……); 清空数

    2024年02月02日
    浏览(41)
  • Peter算法小课堂—线性dp

    今天,你读完这篇文章,普及组的动态规划已经可以秒了。 求两个数列的最长公共子序列(Longest Common Subsequence,LCS)的长度。 数列 X 和 Y 的最长公共子序列 Z,是指 Z 既是 X 的子序列,又是 Y 的子序列,而且任意长度超过 Z 的数列 Z∗ 都不符合这个性质。 f[i][j]表示

    2024年04月23日
    浏览(37)
  • Peter算法小课堂—自定义容器

    这个算法复杂度为O(nm),显然有更快的算法  但是,这样写有个很危险的错误,如下 运行出来是这样的,  原因很简单,因为set的功能是排序、去重,然而结构体排序要加上“.\\\",所以会报错 改后代码, 那么,回到原题,代码该怎么写呢? 当然这个代码也有高级版,但要升

    2024年02月04日
    浏览(38)
  • Peter算法小课堂—正整数拆分

    大家可能会想:正整数拆分谁不会啊,2年级就会了,为啥要学啊 正整数拆分有好几种,这里我们列举两种讲。 我们看着第一幅图,头向左转90°,记住你看到的图,再来看第二幅图,你会惊奇的发现:第一幅图向左转90°就变成了第二幅图!因此,我们做出来一道题,就能推

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包