并查集带权并查集

定义 : 

并查集 : 一种数据结构,用于处理一些不相交集合的合并与查询问题;

例题 : 

如 : 有n种元素,分属于不同的n个集合;

有两种操作  :

  1.给出两个元素的亲属关系,合并两个集合(x与y是亲戚,亲戚的亲戚是亲戚);

于是[x所在的集合] 与 [y所在的集合] 合并;

2. 查询两个元素是否存在关系(是否再统一个集合之中)

实现 : 

那么如何用数据结构来实现并查集呢?

一个集合构建一棵树,人选一个元素作为该集合的根节点,建立pre数组记录每个元素的父节点,pre[当前结点] = 父节点,根节点的父节点 = 自身本身 ;

将并查集,那么肯定有并 和 查 两个部分 :

并 : 

那么给出元素关系之后,如何合并两个集合呢?

将一个集合的树编程另一个集合的字数(将一个集合的根节点的父节点 改为 另一个集合的根节点),用代码来表示也就是 : pre[B的根节点] = A 的根节点 , 就可以将两棵树合并为一棵树 (也就是森林转树);

如何查询两个元素是否属于同一个集合呢?

从该元素开始访问父节点(一般递归查找),知道一步步访问到根界点,再对两个元素的根节点进行对比判断(相同就属于同一集合 , 不相同就不属于同一个元素);

查找根节点的模板 : 

    int find(int x){if (pa[x] != x)pa[x] = find(pa[x]);return pa[x];}

优化(路径压缩):

当上面并查集遇到这样的树的时候,时间优化就基本上没有了;

那么该如何避免这种情况呢?

这个时候就要用到路径压缩优化算法;

能发现 : 再查询操作时,最终目的 : 找到这个元素所在的这棵树的根结点,那么它和其它元素是如何联系的,对我们来说就没有任何意义了;

所以我们可以在每次查询结点的时候,对被查询结点到父节点沿途经过的结点进行一步路径压缩,将经过结点的父节点都更改为根节点 , 也就是 pre[经过结点] = 根节点;

让树的形状尽量接近下面 : 

算法模板 : 

基本模板
template <class T> struct DDS
{int pa[N], num[N];int size;void init(int x){size = x;for (int i = 1; i <= size; ++i)pa[i] = i;}int find(int x){if (pa[x] != x)pa[x] = find(pa[x]);return pa[x];}
};

路径和模板
template <class T> struct DDS
{int pa[N], num[N];int size;void init(int x){size = x;for (int i = 1; i <= size; ++i)pa[i] = i;}int find(int x){if (pa[x] == x || pa[pa[x]] == pa[x])return pa[x];int p = find(pa[x]);num[x] += num[pa[x]];pa[x] = p;return p;}
};

例题 : (NOI 2001 食物链)

链接 : 活动 - AcWing

带权并查集

两个元素建立联系时,并不只是将他们所在的集合合并,还要给它们之间赋一个权值,来表示它们之间的关系;

路径压缩时,3与1的关系要改为re[3]+re[2],但是只有0,1,2三种关系,所以还要对3取模;

在集合合并的时候,根节点之间的关系该如何赋值呢?

已知 x 对 y 的关系 : k, 还知道x对A的关系值 : re[x], Y对B的关系值 : re[y],用向量的思维,那么A对B的关系就是 : re[A] = k+re[y] - re[x] , 但是 re[y] - re[x] 是可能为负值的,所以改为 : re[A] = (k+re[y]-re[x] + 3) mod 3 ;

模板 : 

int parent[N];
LL score[N];int find(int x){ // 找祖宗结点 if(x != parent[x]){int t = parent[x]; // 父节点 parent[x] = find(parent[x]); // 路径压缩score[x] += score[t]; // 加权合并 }		return parent[x];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/230780.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

调研活动怎么做_及时掌握市场趋势

标题&#xff1a;掌握市场趋势&#xff0c;开启调研之旅 一、调研活动的重要性 在当今竞争激烈的市场环境中&#xff0c;了解市场趋势和客户需求至关重要。通过开展有效的调研活动&#xff0c;企业可以获取准确的市场信息和用户反馈&#xff0c;为产品研发、市场营销和战略规…

AKConv:具有任意采样形状和任意数目参数的卷积核

文章目录 摘要1、引言2、相关工作3、方法3.1、定义初始采样位置3.2、可变卷积操作3.3、扩展AKConv3.3、扩展AKConv 4、实验4.1、在COCO2017上的目标检测实验4.2、在VOC 712上的目标检测实验4.3、在VisDrone-DET2021上的目标检测实验4.4、比较实验4.5、探索初始采样形状 5、分析…

L1-003:个位数统计

题目描述 给定一个 k 位整数 Ndk−1​10k−1⋯d1​101d0​ (0≤di​≤9, i0,⋯,k−1, dk−1​>0)&#xff0c;请编写程序统计每种不同的个位数字出现的次数。例如&#xff1a;给定 N100311&#xff0c;则有 2 个 0&#xff0c;3 个 1&#xff0c;和 1 个 3。 输入格式&#…

序列号管理

序列号管理&#xff0c;将从以下方面进行学习和阐述 WHY 为什么需要序列号&#xff0c;有什么作用 HOW sap如何进行管理序列号 WHEN 什么情况下适合进行序列号管理 1、 什么是序列号 首先简单介绍一个序列号是什么东西&#xff0c;我们使用的手机、电脑或者大家…

Element的安装与基本使用

文章目录 一.什么是Element?二.Element的安装(Vscode)三.在Vue项目中引入ElementUI组件库四.编写Element的Vue组件文件五.演示如何使用Element官网中的组件根组件中引入Element组件内容进行网页展示 一.什么是Element? Element是饿了么团队研发的一套为开发者与设计师等准备…

centos7-docker安装与使用

文章目录 一、docker简介1.1docker应用场景1.2docker的优点1.2.1快速&#xff0c;一致地交付应用程序1.2.2响应式部署和扩展1.2.3在同一硬件上运行更多工作负载 1.2docker的架构 二、docker的安装2.1新系统的环境搭建2.1.1更换yum源 2.2安装docker与卸载2.2.1yum安装docker2.2.…

set与map

set与map 一、序列式容器与关联式容器二、pair1、键值对2、作用3、构造函数4、make_pair&#xff08;1&#xff09;构造函数&#xff08;2&#xff09;作用 5、代码6、运行结果 三、set1、概念2、代码3、运行结果4、说明 四、multiset1、与set的关系2、代码3、运行结果 五、map…

【Shell】Shell基础学习

一、shell脚本 (1)第一个shell脚本 #!/bin/bash #this is a comment echo "hello world"一个shell脚本永远以“#!”开头,这是一个脚本开始的标记,它是告诉系统执行这个文件需要用某个解释器,后面的/bin/bash就是指明解释器的具体位置。 “#”开头是注释 …

班主任每日工作流程

以下是班主任的每日工作流程&#xff0c;虽然每天的工作都很繁琐&#xff0c;但是为了学生的成长和发展&#xff0c;班主任们必须认真履行职责&#xff0c;用自己的爱心和责任心去呵护每一个学生。 早晨7&#xff1a;30到校&#xff0c;组织学生打扫卫生&#xff0c;检查学生作…

数据库管理-第118期 记一次开启附加日志导致的性能问题(202301129)

数据库管理-第118期 记一次开启附加日志导致的性能问题&#xff08;202301129&#xff09; 本周二凌晨&#xff0c;为了配合某国产数据库从Oracle数据库能够实时同步数据&#xff0c;在X9M那套一体机上做了开启附加日志的操作&#xff0c;也正是因为这个操作带来了一些小问题。…

mybatis参数输入 #{}和${}

1、建库建表 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_emp(emp_id INT AUTO_INCREMENT,emp_name CHAR(100),emp_salary DOUBLE(10,5),PRIMARY KEY(emp_id) );INSERT INTO t_emp(emp_name,emp_salary) VALUES("tom",200.33); INSERT INTO…

深入Python元编程:了解声明与初始化定制元类

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 简介 在Python中&#xff0c;元编程是指在运行时创建或定制类的编程。元类是Python中最强大的元编程工具之一&#xff0c;允许您控制类的创建过程。元类是类的类&#xff0c;它控制类的实例化&#xff0c;允许您…