并查集OJ做题报告

并查集

洛谷P3367

模板并查集

以后要注意的:

  1. scanf函数括号里面要写好,先双引号" " ,再用逗号,将输入内容和变量分开

洛谷P1525

关押罪犯

学到了:

  1. sort函数的第三个参数,该参数是一比较参数,决定排序完数据是升序还是降序
cpp 复制代码
bool cmp(int a,int b){
	return a>b;//可以理解为当a>b时把a放在b前面,就是升序
	//return a<b;可以理解为当a<b时把a放在b前面,就是降序
}
  1. 结构体数组排序
    1. 先定义结构体
cpp 复制代码
struct node{
	int a,b,c;
}x[10];
  1. 输入数据
cpp 复制代码
for(int i=1;i<=m;i++){
		scanf("%d %d %d",&x[i].a,&x[i].b,&x[i].c);
		} 

3.设立比较条件

  • 一级排序(将c从大到小排序)
cpp 复制代码
bool cmp(node i,node j){
	return i.c>j.c;
}
  • 二级排序(c相等的情况下,按照b大小来从小到大排序)
cpp 复制代码
bool cmp(node i,node j){
	if(i.c==j.c){
		return i.b>j.b;
	}else{
		return i.c>j.c;
	}
}

以后要注意的:

  • 种类并查集就是找出有哪些不同种类(不同集合)
  • 在一数组上划分不同的状态(比如i为正状态,则i+n为反状态,两者不共存)
  • 当题目要求分开x和y时,我们就需要合并x和y的反状态,y和x的反状态
  • 判断是否已经区分就是查看是否在一个集合(普通并查集),找父节点

洛谷CF776D

CF776D The Door Problem

思路:

怎么想到用并查集的?

  1. 我们已经得知每盏灯的初始状态和哪两个开关控制它。

  2. 首先分类讨论:

    • 如果最开始这盏灯是开着的,那么这两个开关应该做出同样的操作,即要么全按,要么全不按。

    • 如果最开始这盏灯是关着的,那么这两个开关应该做出不同的操作,即一个按一个不按。

    • 转化一个思路,就变成了有 m 个数,其中有 n 个关系,有些关系是两个数要一样,有些关系是两个数要不一样,问是否合理。

  3. 维护开与关的关系,我们想到了并查集。

该题目最重要的一句话:每扇门恰好被两个开关控制

而每扇门只有两个状态:

  1. 0状态,房间门是锁着的
  2. 1状态,房间门的开着的

依题意现在每一扇门对应两个钥匙,设门为开 的状态为(u,v),设门为关 的状态为(u+m,v+m)且一共有m个开关数,则:

  • 对于开着的门:

    合并(u,v),(u+m,v+m)

    • 同种状态钥匙开一遍才能保持门是"开"的状态
  • 对于关着的门:

    合并(u,v+m),(u+m,v)

    • 不同种状态的钥匙开一遍才能保证门是关着的

当合并完之后,我们只需要遍历所有开关数 i ,当发现i与i+m在同一集合,则输出 "NO",因为一把钥匙只能有使用或不使用的状态.所以如果i和i+m在一个并查集内,这是不合法的

这一流程用并查集文字意思就是:

  • 遍历每一个门的时候赋予每一个开关开或不开的状态,当有一个开关矛盾了(就是开和不开同时需要满足),则依题意输出 "NO"。

这里的输入流程比较麻烦:

  1. 输入房间数和开关数
  2. 输入房间状态(基于房间数)
  3. 输入控制房间数量
  4. 输入钥匙控制房间的编号(基于第3点)
    • 这里要用一个结构体数组来存数据,数组下标是房间号,结构体里面是能控制对应房间号的两个钥匙
cpp 复制代码
struct key{
	int a,b;
}x[200005];
for(int i=1;i<=m;i++){		//i是开关编号 
		int c;
		scanf("%d",&c);			//控制的房间数量 
		for(int j=1;j<=c;j++){
			int d;
			scanf("%d",&d);		//被控制的房间编号
			if(x[d].a==0){
				x[d].a=i; 		//房间编号d由2个开关中的i开关控制 
			}else{
				x[d].b=i;
			}
		}
	}
}

以后要注意的:

  1. 处理并查集时始终用一个函数来合并集合,避免直接修改父节点数组(或者修改完父节点数组后再次重新查找父节点),因为这会破坏路径压缩,导致循环引用或造成错误的集合关系,破坏了并查集结构
相关推荐
怕浪猫4 小时前
RAG 面试 6 连问,从原理到优化全部覆盖
python·算法·面试
无线通信科研笔记5 小时前
IEEE TVT 2026 论文精读与完整复现|相位误差如何重塑近场 RIS 的幅相响应
论文阅读·人工智能·python·算法·论文笔记
mmmmath_36 小时前
二叉树の递归遍历
算法
All for pursuit.6 小时前
【位运算-1】338.比特位计数
数据结构·c++·算法·leetcode
小师兄吃牛肉7 小时前
C语言中的nullptr有必要吗
c语言·c++·算法
一只小小的芙厨8 小时前
【线性DP】
学习·算法·动态规划
奋发向前wcx9 小时前
CSP-J复赛模拟赛5 王晨旭补题 2026.10.5
算法
罗湖老棍子10 小时前
C Looooops(信息学奥赛一本通- P1640)
算法·数论·同余·裴蜀定理·扩展欧几里得
飘尘12 小时前
从"算子"到"AI Infra":大模型背后看不见的那群人在忙什么
人工智能·算法·面试
夏幻灵13 小时前
每日一题:LeetCode 3:无重复字符的最长子串——滑动窗口思路详解
算法·leetcode·职场和发展