一篇文章带你通关并查集(持续更新中)

这篇文章的所有题目均来自于自行整理,代码均来自于自行梳理调试(思路可能比较暴力)。初衷在于整理练习思路,且起到督促自己学习的作用

本文分成将三个模块

1.普及组 (洛谷黄题)

2.提高组 (洛谷绿题)

3.省选组 (洛谷蓝题及以上)

一、普及

1.P3367 【模板】并查集

普通并查集(纯板子,不加解释)

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P3367

// Problem: 
//     P3367 【模板】并查集
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3367
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
using namespace std;
const int N=1e4+10;
int e[N];int find(int x){if(x!=e[x]) e[x]=find(e[x]);return e[x];//返回根节点
}void merge(int a,int b){int x=find(a);int y=find(b);//e[x]=y;连接到另外一个上,我看了看板子更加复杂,但是符合原理都能过这里前面加一个if(x!=y)会更好,若不然可能增加路径压缩的次数
}int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;++i) e[i]=i;while(m--){int a,b,c;cin>>a>>b>>c;if(a==1){merge(b,c);}else{int k1=find(b);int k2=find(c);if(k1==k2) cout<<"Y"<<endl;else cout<<"N"<<endl;}}return 0;
}

2.P1551 亲戚

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1551

一道算是应用场景的题目,可以拿来熟熟手

// Problem: 
//     P1551 亲戚
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1551
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
using namespace std;
const int N=5005;
int fa[N];int find(int x){if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];//返回根节点
}void merge(int a,int b){int x=find(a);int y=find(b);fa[x]=y;
}int main(){int n,m,p;cin>>n>>m>>p;for(int i=1;i<=n;++i) fa[i]=i;while(m--){int a,b;cin>>a>>b;merge(a,b);}while(p--){int a,b;cin>>a>>b;int x=find(a),y=find(b);if(x==y) cout<<"Yes"<<endl;else cout<<"No"<<endl;}return 0;
}

3.P1111 修复公路

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1111

五花八门的答案,结合了一点排序知识

本人用了结构体排序后全遍历,O(nm)的时间复杂度(1e8)擦边过了

// Problem: 
//     P1111 修复公路
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1111
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int fa[N];
struct node{int a,b,c;bool operator < (const node &p)const {return c<p.c;};//重载
}nodes[100005];int find(int x){if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];
}void merge(int x,int y){int a=find(x),b=find(y);if(a!=b) fa[a]=b;//还是这么写吧,时间更优一点
}int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;++i) fa[i]=i;for(int i=1;i<=m;++i){cin>>nodes[i].a>>nodes[i].b>>nodes[i].c;}sort(nodes+1,nodes+1+m);for(int i=1;i<=m;++i){merge(nodes[i].a,nodes[i].b);bool check=true;for(int i=2;i<=n;++i){if(find(i)!=find(i-1)){//这里注意合并完没有merge的fa是没有直接更新的,不能直接比较fa[i]check=false;break;}}if(check){cout<<nodes[i].c<<endl;return 0;}}cout<<-1<<endl;return 0;
}

这个地方有更优的方法O(m),遍历一遍,如果遇到根节点不同,连通块数量减一并合并,这样连通块数量等于1的时候,输出答案就好了(只需要操作n-1次)

4.P2814 家谱

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P2814

这道题我个人结合了map,调到吐血,越改越复杂,细节还是蛮多的(不熟练

#include<iostream>
#include<map>
using namespace std;
const int N=5e4+10;
int fa[N];
map<string,int> mp;//记录每个点的标记
map<int,string> mpp;//在最后返回根节点的字符串
int cnt;int find(int x){if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];
}void merge(int f,int a){int x=find(f),y=find(a);if(x!=y) fa[y]=x;
}int main(){string s;int now;while(cin>>s){string k=s.substr(1);if(s=="$") break;else if(s[0]=='#'){if(!mp[k]){mp[k]=++cnt;fa[cnt]=cnt;now=cnt;mpp[cnt]=k;}else now=mp[k]; }else if(s[0]=='+'){if(!mp[k]){mp[k]=++cnt;fa[cnt]=cnt;mpp[cnt]=k;}merge(now,mp[k]);}else{int t=find(mp[k]);
//这个地方WA了n发,因为最后步find,这里还保留的是上一次的father,要find一次才能更新cout<<k<<' '<<mpp[t]<<endl;}}	return 0;
}

除了我的代码外,这里奉上大佬的一个题解,一样的思路,但是代码简单,炉火纯青。

(我被板子局限了思路,确实没想到路径压缩可以直接压缩map)

5.P1536 村村通

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1536

这道题如果把前面的吃透了,想起本文第三题结尾大佬的一个办法,计算连通块数量,如果find查找的根节点不同,就连通块数量-1并合并,连通块开始初始化为n-1。

// Problem: 
//     P1536 村村通
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1536
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
using namespace std;
const int N=1005;
int fa[N];int find(int x){if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];
}void merge(int a,int b){int x=find(a),y=find(b);if(x!=y) fa[x]=y;
}int main(){int a,b;while(cin>>a){if(a==0) break;for(int i=1;i<=a;++i) fa[i]=i;cin>>b;int ans=a-1;while(b--){int x,y;cin>>x>>y;if(find(x)!=find(y)) ans--,merge(x,y);}if(ans>=0) cout<<ans<<endl;else cout<<0<<endl;}	return 0;
}

这种方法的初衷其实更适合实时在某一刻卡断一类的,就是说能知道各时刻连通块的数量,这道题其实暴力就可以解决掉(因为给的全部都要操作)

6.P3958 [NOIP2017 提高组] 奶酪

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P3958非常伤心,这道题卡了我两个钟,最终发现原因(h的范围是1e9,不能直接暴力,写假了)

其实就是一段算成一个点,合并集合,最后把上下两个面再维护一下,看看上下两个面在不在一个集合里,可以配合这篇:远古大神 食用~

// Problem: 
//     P3958 [NOIP2017 提高组] 奶酪
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3958
// Memory Limit: 250 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1003;
#define int long long
int fa[N];
int n,h,r;
struct node{int a,b,c;
}nodes[N];
bool check(node x,node y){int num=(x.a-y.a)*(x.a-y.a)+(x.b-y.b)*(x.b-y.b)+(x.c-y.c)*(x.c-y.c);if(num>(2*r*r*2)) return false;return true;
}
int find(int x){if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];
}
void merge(int a,int b){int x=find(a),y=find(b);if(x!=y) fa[y]=x;//高的往低处接
}
signed main(){int t;cin>>t;while(t--){cin>>n>>h>>r;for(int i=1;i<=n+2;++i) fa[i]=i;for(int i=1;i<=n;++i){cin>>nodes[i].a>>nodes[i].b>>nodes[i].c;}for(int i=1;i<=n;++i){for(int j=i+1;j<=n;++j){if(check(nodes[i],nodes[j])){merge(i,j);}}}for(int i=1;i<=n;++i){if(nodes[i].c-r<=0) merge(i,n+1);if(nodes[i].c+r>=h) merge(i,n+2);//看看能不能串起来}if(find(n+1)==find(n+2)) cout<<"Yes"<<endl;else cout<<"No"<<endl;}return 0;
}

二、提高

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

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

相关文章

sqlserver 默认端口号不通 1433 开启监听

1.打开SQL Server 2022 配置管理器 查看这3个东西是否启用&#xff0c;然后双击TCP/IP 把默认端口全部设置成1433 然后cmd netstat -an | find "1433" 查看端口是否打开监听

存储架构 NAS 与 SAN:有什么区别?

SAN&#xff08;Storage Area Network&#xff09;和NAS&#xff08;Network Attached Storage&#xff09;是两种存储架构&#xff0c;它们在数据存储和管理方面有着不同的设计理念和应用场景。SAN通常将存储设备连接到一个独立的高速网络&#xff0c;而NAS则通过普通的网络协…

Unity性能优化篇(九) 模型优化之LOD技术概述以及操作方法

LOD模型优化技术概述: 1.LOD技术可以根据摄像头远近来显示不同精度的模型(例如吃鸡游戏 随着跳伞高度 来显示下面树木以及建筑的模型精度) LOD模型优化技术操作方法: 可使用Unity自带的LOD Group组件&#xff0c;并根据项目的情况来调整该组件的属性。Untiy资源商店也有一些其…

如何选择VR全景设备,才能拍摄高质量的VR全景?

随着VR全景技术的不断成熟和发展&#xff0c;VR全景已经成为了摄影爱好者乐于尝试的新手段&#xff0c;VR全景也为广大用户提供了一个全新的视角来探索世界&#xff0c;如果想要拍摄出高质量的VR全景&#xff0c;选择合适的VR全景拍摄设备以及掌握正确的拍摄技巧才是关键。 VR全…

云手机:网页运行?易用性分析

云手机作为一种新兴的技术&#xff0c;近年来在移动互联网领域备受关注。它通过云计算技术&#xff0c;将手机的操作系统和应用程序运行在远程服务器上&#xff0c;用户通过网络连接访问和操作云手机&#xff0c;从而实现了在任何设备上都能够享受手机的功能和体验。本文将探讨…

vue系列——vscode,node.js vue开发环境搭建

第一步安装node.js 推荐使用nvm进行node.js 的安装 nvm(Node.js version manager) 是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 可以去网上查找相关版本 我这里使用 nvm-setu… 链接:https://pan.baidu.com/s/1UEUtmzw5x…

代码随想录算法训练营第三十九天|动态规划|62.不同路径、63. 不同路径 II

62.不同路径 文章 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

12.WEB渗透测试-Linux系统管理、安全加固(下)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;11.WEB渗透测试-Linux系统管理、安全加固&#xff08;上&#xff09;-CSDN博客 Linux任务…

好书安利:《大模型应用开发极简入门:基于GPT-4和ChatGPT》这本书太好了!150页就能让你上手大模型应用开发

文章目录 前言一、ChatGPT 出现&#xff0c;一切都变得不一样了二、蛇尾书特色三、蛇尾书思维导图四、作译者简介五、业内专家书评总结 前言 ​如果问个问题&#xff1a;有哪些产品曾经创造了伟大的奇迹&#xff1f;ChatGPT 应该会当之无愧入选。仅仅发布 5 天&#xff0c;Chat…

【RabbitMQ】WorkQueue

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;MQ ⛺️稳中求进&#xff0c;晒太阳 Work Queues Work queues任务模型&#xff0c;简单来说就是让多个消费者绑定到一个队列&#xff0c;共同消费队列中的消息 当消息处理比较耗时的时候&…

力扣112 路径总和 Java版本

文章目录 题目描述解题思路代码 题目描述 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0…

新型设备巡检方案-手机云巡检

随着科技的不断发展&#xff0c;设备巡检工作也在逐步向智能化、高效化方向转变。传统的巡检方式往往需要人工逐个设备检查&#xff0c;耗时耗力&#xff0c;效率低下&#xff0c;同时还容易漏检和误检。而新型设备巡检应用—手机蓝牙云巡检的出现&#xff0c;则为设备巡检工作…

每日OJ题_链表②_力扣24. 两两交换链表中的节点

目录 力扣24. 两两交换链表中的节点 解析代码 力扣24. 两两交换链表中的节点 24. 两两交换链表中的节点 难度 中等 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&…

Java定时调度范式定时操作

在 Java 中&#xff0c;我们可以使用各种方法来执行定时操作。这些操作包括执行任务、调度任务、执行重复任务等。下面将介绍几种常见的 Java 定时调度范式。 1. Timer 和 TimerTask Java 提供了 Timer 和 TimerTask 类&#xff0c;用于执行定时任务。 示例代码&#xff1a;…

MyBatis操作数据库(SQL注入)

本文主要来讲解6大标签&#xff0c;以便更好的MyBatis操作数据库&#xff01; <if>标签<trim>标签<where>标签<set>标签<foreach>标签<include>标签 前提需求&#xff1a; MyBatis是一个持久层框架&#xff0c;和Spring没有任何关系&…

【力扣白嫖日记】1070.产品销售分析III

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 1070.产品销售分析III 表&#xff1a;Sales 列名类型sale_idintproduct_idintyearintquantityintpriceint …

Mybatis-Plus Mapper映射文件使用

介绍 MyBatis 的真正强大在于它的语句映射&#xff0c;这是它的魔力所在。由于它的异常强大&#xff0c;映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比&#xff0c;你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本&#xff0…

day2 FreeRTOS

思维导图 1.使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度。 HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);//打开定时器3的通道3并且设置为PWM功能/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */int adc_val 0;while (1){HAL_…

Day15:技术架构、Maven、Spring Initializer、Spring全家桶、Spring IoC

侧重于服务端&#xff08;后端&#xff09;&#xff0c;不在意前端&#xff0c;了解一些前端即可&#xff09; 技术架构 &#xff08;把Spring设计的更简单好用了就是Spring Boot&#xff09; 开发环境&#xff08;Maven&#xff09; Maven maven通过brew安装的目录为&#x…

开放式高实时高性能PLC控制器解决方案-基于米尔电子STM32MP135

前言 随着工业数字化进程加速与IT/OT深入融合&#xff0c;不断增加的OT核心数据已经逐步成为工业自动化行业的核心资产&#xff0c;而OT层数据具备高实时、高精度、冗余度高、数据量大等等特点&#xff0c;如何获取更加精准的OT数据对数字化进程起到至关重要的作用&#xff0c;…