并查集——以nuist OJ P1648炼丹术为例
并查集
定义:并查集是一种树形的数据结构,用于处理一些不相交集合的合并及查询问题
主要构成:
并查集主要由一个整型数组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**i⩽n) 表示药材 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炼丹术为例的更多相关文章
- Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands)
Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands) N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并 ...
- 安科 OJ 1190 连接电脑 (并查集)
时间限制:1 s 空间限制:128 M 传送门:https://oj.ahstu.cc/JudgeOnline/problem.php?id=1190 题目描述 机房里有若干台电脑,其中有一些电脑已经 ...
- 并查集练习(0743) SWUST OJ
#include<iostream> #include<cstring> using namespace std; ]; int n,m,l,ci,di; int root(i ...
- 杭电OJ——1198 Farm Irrigation (并查集)
畅通工程 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可 ...
- 洛谷OJ P1196 银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
- 九度OJ 1446 Head of a Gang -- 并查集
题目地址:http://ac.jobdu.com/problem.php?pid=1446 题目描述: One way that the police finds the head of a gang ...
- 九度OJ 朋友圈 -- 并查集
题目地址:http://ac.jobdu.com/problem.php?pid=1526 题目描述: 假如已知有n个人和m对好友关系(存于数字r).如果两个人是直接或间接的好友(好友的好友的好友.. ...
- [Swust OJ 772]--Friend(并查集+map的运用)
题目链接:http://acm.swust.edu.cn/problem/772/ Time limit(ms): 1000 Memory limit(kb): 65535 Descriptio ...
- [Swust OJ 1091]--土豪我们做朋友吧(并查集,最值维护)
题目链接:http://acm.swust.edu.cn/problem/1091/ Time limit(ms): 1000 Memory limit(kb): 32768 人都有缺钱的时候,缺 ...
随机推荐
- TIME_WAIT 优化
·[场景描述] HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟. 如果我们使用了nginx去作为 ...
- 前端每日实战:144# 视频演示如何用 D3 和 GSAP 创作一个集体舞动画
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/gdVObN 可交互视频 此视频是可 ...
- Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏
本文绘制的地图效果图如下: 一.Echarts 使用五部曲 1.下载并引入 echarts Echarts 已更新到了 5.0 版本,安装完记得检查下自己的版本是否是 5.0 . npm instal ...
- docker将jar打包镜像文件
1.首先需要编写dockerfile文件,通过dockerfile文件将jar包打成镜像 编写dockerfile文件 # 定义父镜像 FROM java:8 # 维护者信息 MAINTAINER c ...
- Jenkins+Allure测试报告+飞书机器人发送通知
一.前言 之前讲了jenkins如何设置定时任务执行脚本,结合实际情况,本篇讲述在jenkins构建成功后,如何生成测试报告,以及推送飞书(因为我公司用的是飞书,所以是发送到飞书机器人). 本次实践搞 ...
- 【大话云原生】煮饺子与docker、kubernetes之间的关系
云原生的概念最近非常火爆,企业落地云原生的愿望也越发强烈.看过很多关于云原生的文章,要么云山雾罩,要么曲高和寡. 所以笔者就有了写<大话云原生>系列文章的想法,期望用最通俗.简单的语言说明 ...
- Python学习笔记: getpass module: 安全输入密码
使用场景 使用input()函数接收用户输入的时候会将用户输入回显,对于密码肯定是不适用的.标准库里面有getpass module提供了安全输入不回显 getpass module有2个函数 get ...
- 华为麒麟团队力造的Python,整整26G
华为团队力造的Python,下面链接自取 https://docs.qq.com/doc/DRkZvRkxvb292c2Vz
- 分布式任务调度平台XXL-JOB安装及使用
一.为什么需要任务调度平台 在Java中,传统的定时任务实现方案,比如Timer,Quartz等都或多或少存在一些问题: 不支持集群.不支持统计.没有管理平台.没有失败报警.没有监控等等而且在现在分布 ...
- python学习-Day39-HTML-form表单
目录 HTML-form表单 form表单 属性action input标签(输入元素) 文本域(Text Fields) 密码字段 单选按钮(Radio Buttons) 复选框(Checkboxe ...