并查集

定义:并查集是一种树形的数据结构,用于处理一些不相交集合的合并及查询问题

主要构成:

并查集主要由一个整型数组pre[]和两个函数find()、join()构成。

数组pre[]记录了每个点的前驱结点是谁,函数find(x)用于查找指定结点x属于哪个集合,函数join(x,y)用于合并两个结点x和y。

作用:

并查集的主要作用是求联动分支数。

代表元:

用集合中的某个元素来代表这个集合,则该元素称为此集合的代表元

find()函数的定义与实现:

int find(int x){while(pre[x]!=x) //如果代表元不是自己x = pre[x];     //x继续向上找其上级,直到找到代表元为止return x;
}

join()函数的定义与实现:

void join(int x,int y){int fx = find(x),fy=find(y);if(fx!=fy)pre[fx] = fy;
}

路径压缩算法:将x到根节点路径上的所有点的上级都设为根节点

//递归实现
int find(int x){if(pre[x] == x) return x;return pre[x] = find(pre[x]);
}
//循环实现
int find(int x) {while(x!=pre[x])x=pre[x]=pre[pre[x]];return x;
}

总结:

1、用集合中的某个元素来代表这个集合,则该元素称为此集合的代表元;
2 、一个集合内的所有元素组织成以代表元为根的树形结构;
3 、对于每一个元素 x,pre[x] 存放 x 在树形结构中的父亲节点(如果 x 是根节点,则令pre[x] = x);
4 、对于查找操作,假设需要确定 x 所在的的集合,也就是确定集合的代表元。可以沿着pre[x]不断在树形结构中向上移动,直到到达根节点。
因此,基于这样的特性,并查集的主要用途有以下两点:
1、维护无向图的连通性(判断两个点是否在同一连通块内,或增加一条边后是否会产生环);
2、用在求解最小生成树的Kruskal算法里。

//代码汇总
const int N = 1005 //指定并查集所能包含的元素个数
int pre[N];
int rank[N];
void init(int n){for(int i=0;i<n;i++){pre[i] = i;//每个节点的上一级都是自己rank[i] = 1;}
}
int find(int x){if(pre[x] == x) return x;return find(pre[x]);
}
int find(int x){if(pre[x] == x) return x;return pre[x] = find(pre[x]);
}
//判断两个结点是否连通
bool isSame(int x,int y){return find(x) == find(y);
}bool join(int x,int y){x = find(x);y = find(y);if(x == y) return false;if(rank[x] >rank[y]) pre[y] = x;else{if(rank[x] == rank[y]) rank[y]++;pre[x] = y;}return true;
}

例:炼丹术

题目描述

三水最近在学习炼丹术。但是众所周知炼丹术是一门危险的学科,需要大量的调参才能保证安全。好在三水在洗衣机里面找到了一张失传已久的图纸,里面记录了若干种材料的药性。这张图纸上记录了 n种不同的药材,对于每种药材,都需要恰好一种药材来使其稳定 (这种药材可能是其自身,即这种药材本身就很稳定)。三水想知道,通过这张图纸,可以得到多少种不同的稳定的丹方。保证每种药材只会作为稳定剂出现一次。

我们认为一个丹方是从 n种药材中选择若干种 (不为 0 ),两个丹方被认为是不同的当且仅当存在一种药材在其中一个丹方中且不在另一个中。我们称一个丹方是稳定的,当且仅当所有出现在丹方中的药材的稳定剂也在药材中。

因为输出结果可能很大,所以答案对 998244353 取模。

输入描述

第一行一个数字 nn , 表示有 n (1\leqslant n\leqslant 10^6)n(1⩽n⩽106) 种不同的药材。 接下来一行 n个数字,第 i数字 a_i (1\leqslant a_i\leqslant n)a**i(1⩽a**in) 表示药材 ii 的稳定剂是 a_ia**i,保证输入是 11 到 nn 的一个全排列。

输出描述

一个整数 nn ,表示答案对 998244353 取模的结果。

样例输入
 6 2 3 4 5 6 1
样例输出
 1
思路:

AC代码
#include<cstdio>
#include<iostream>
const int MAXN=1000005;
const int INF=0x3f3f3f3f;
const int mod=998244353;using namespace std;int pre[MAXN], a[MAXN];int find(int x) {while(x!=pre[x])x=pre[x]=pre[pre[x]];return x;
}
int pow(int n) {int ans=1,base=2;for(int i=1;i<=n;++i) {ans=(ans*base)%mod;}return ans;
}
int main() {int n;scanf("%d",&n);for(int i=1;i<=n;++i) {scanf("%d",&a[i]);pre[i]=i;//初始化查数组}for(int i=1;i<=n;++i) {int u=find(i), v=find(a[i]);//通过前缀数组更新并查集,查询过程中进行路径压缩if(u!=v)pre[u]=v;         //合并相关联集合}int cnt=0;for(int i=1;i<=n;++i) {         //记录不同集合个数if(pre[i]==i) cnt++;}printf("%d",pow(cnt)-1);return 0;
}

并查集——NUIST OJ P1648 炼丹术为例相关推荐

  1. 连通图的判断(并查集, DFS, BFS)

    首先要明确什么是连通图??? 连通图:对于一个图来说,图中的任意一个点都能访问到所有的点,则说明该图连通 很明显,如果要判断一个图是否连通,则必须要从任意一个搜索一遍,判断是否到达了所有的点,则很快会 ...

  2. 安科 OJ 1190 连接电脑 (并查集)

    时间限制:1 s 空间限制:128 M 传送门:https://oj.ahstu.cc/JudgeOnline/problem.php?id=1190 题目描述 机房里有若干台电脑,其中有一些电脑已经 ...

  3. 并查集练习(0743) SWUST OJ

    #include<iostream> #include<cstring> using namespace std; int a[1000005]; int n,m,l,ci,d ...

  4. 海贼OJ并查集练习题:朋友圈

    海贼OJ并查集练习题:朋友圈 题目描述 ​ 所谓一个朋友圈子,不一定其中的人都互相直接认识. ​ 例如:小张的朋友是小李,小李的朋友是小王,那么他们三个人属于一个朋友圈. ​现在给出一些人的朋友关系, ...

  5. hrbust 哈理工oj 1418 夏夜星空【带权并查集】

    夏夜星空 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 43(20 users) Total Accepted: 19(18 user ...

  6. 【bzoj 入门OJ】[NOIP 热身赛]Problem C: 星球联盟(并查集)

    Problem C: 星球联盟 Time Limit: 4 Sec  Memory Limit: 256 MB Submit: 57  Solved: 15 [Submit][Status][Web ...

  7. PIPI OJ 1118: 继续畅通工程(并查集+最小生成树)

    菜鸟生成记(18) 1118: 继续畅通工程 又双叒叕是最短路径的水题;不同的是,在构造最小生成树前,题目中已经规定一些已经建好了(这些边已经在生成树里面了);从未建好的边中选择最优边加入生成树;直到 ...

  8. 算法:程序设计之并查集

    前言 之前一直都是听说并查集,感觉是一个神乎其技,狂拽酷炫.却没有想过在自己学习并查集之前,自已在解决问题的时候也能够想到一个和并查集异曲同工的方法.这个还是很愉快的. 版权说明 著作权归作者所有. ...

  9. HZNUOJ 2977 宝可梦决战 种族并查集

    原题链接: https://acm.hznu.edu.cn/OJ/problem.php?id=2977https://acm.hznu.edu.cn/OJ/problem.php?id=2977 D ...

最新文章

  1. 【Java源码分析】ArrayList源码分析
  2. 48.聊一聊constexpr变量
  3. IE 8 Accelerator加速器开发介绍{转载}
  4. Python打卡第四周
  5. android环境搭建出错,androidstudio配置环境遇到的各种错误(持续更新中)
  6. 新疆农业大学计算机科学与技术专业怎么样,新疆农业大学计算机科学与技术专业2016年在新疆理科高考录取最低分数线...
  7. 只限女生!谷歌 2020 Women Techmakers 奖学金项目申请开启!
  8. [转]JAVA与.NET DES加密解密
  9. 《数学之美》—PageRank
  10. Effective C# 原则3:选择is或者as操作符而不是做强制类型转换(翻译)
  11. 黑苹果电池电量补丁_【黑苹果】用一次实战记录电池热补丁的编写方法
  12. 联想E14笔记本 不插鼠标出现鼠标自动漂移乱串
  13. mysql报duplicate_mysql DUPLICATE KEY UPDATE 问题
  14. 手机通讯录excel转换vcf
  15. 阿里P8面试官总结的《2021最新java面试题》,搞定90%以上的技术面
  16. Prometheus配置企业微信报警
  17. 【监控】Prometheus(普罗米修斯)监控概述
  18. c语言程序 出圈游戏,【出圈】 (C语言代码)
  19. WinXP系统怎么重装?
  20. 常用的四种sql增删改查

热门文章

  1. Js——ScrollTop、ScrollHeight、ClientHeight、OffsetHeight汇总
  2. 手把手带你了解一块电路板,从设计到制作(干货)
  3. 【四轴飞行器】【电机部分】PWM驱动空心杯转速
  4. 魅族mx四核即将使用android,魅族MX四核真机主板曝光 6月份即将上市
  5. 何海涛算法面试题感悟之六:二元查…
  6. 高效电脑工具Wox+everything
  7. 初级网管或黑客必需撑握的8个DOS命令
  8. php许愿墙mysql_基于Apache+php+mysql的许愿墙网站的搭建
  9. python自然语言处理-学习笔记(一)之nltk入门
  10. 关于superfetch