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

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

本文分成将三个模块

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;
}

二、提高

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法-线性查找

引言 在计算机科学领域&#xff0c;数据结构和算法是构建高效软件系统的核心要素。今天我们将聚焦于最基础且广泛应用的一种查找算法——线性查找&#xff0c;并探讨其原理、实现步骤以及实际应用场景。 一、什么是线性查找&#xff1f; 线性查找&#xff08;Linear Search&am…

腾讯云哪款服务器最便宜划算?2024腾讯云服务器优惠价格表

腾讯云优惠活动2024新春采购节活动上线&#xff0c;云服务器价格已经出来了&#xff0c;云服务器61元一年起&#xff0c;配置和价格基本上和上个月没什么变化&#xff0c;但是新增了8888元代金券和会员续费优惠&#xff0c;腾讯云百科txybk.com整理腾讯云最新优惠活动云服务器配…

嵌入式学习第二十六天!(网络传输:TCP编程)

TCP通信&#xff1a; 1. TCP发端&#xff1a; socket -> connect -> send -> recv -> close 2. TCP收端&#xff1a; socket -> bind -> listen -> accept -> recv -> send -> close 3. TCP需要用到的函数&#xff1a; 1. co…

CIA402协议笔记

文章目录 1、对象字典1.1 Mode of Operation&#xff08; 606 0 h 6060_h 6060h​)1.2 Modes of opration display( 606 1 h ) 6061_h) 6061h​) 2、状态机2.1 控制字&#xff08;ControlWord、6040h&#xff09;2.2 状态字&#xff08;StatusWord、6041h&#xff09;2.3 shutd…

练习 6 Web [极客大挑战 2019]HardSQL

[极客大挑战 2019]HardSQL 先尝试登录&#xff0c;查看报错信息 admin 111 password 1111 登录失败admin 111 password 1’or’1 登录成功 这里直接试了万能密码成功&#xff0c;复习一下&#xff0c;第一个 ’ 是为了闭合前面的sql语句&#xff0c;最后的1后面没有 ’ 是因为…

钉钉群内自定义机器人发送消息功能实现

文章目录 钉钉群内自定义机器人发送消息功能实现1、设置webhook自定义机器人2、查看官方文档&#xff0c;使用open api3、编写业务代码4、发送成功结果如下 钉钉群内自定义机器人发送消息功能实现 1、设置webhook自定义机器人 设置关键词 添加完成后&#xff0c;获得改机器人的…

【R语言实战】聚类分析及可视化

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

外包干了8天,技术退步明显。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入杭州某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

泰克P6139B TektronixP6139B无源探头

特征&#xff1a; 500 MHz 探头带宽 探头尖端的大输入阻抗 10 MOhm&#xff0c;8 pF 补偿范围&#xff1a;8 pF 至 18 pF 电缆长度&#xff1a;1.3M 10X 衰减系数 300 V CAT II 输入电压 用于探测小几何电路元件的紧凑型探头 用于增强被测设备可见性的小型探头主体 可更换的探…

Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍

1.简介 学习音视频开发&#xff0c;首先从做一款播放器开始是比较合理的&#xff0c;每一章节&#xff0c;我都会将源码贴在最后&#xff0c;此专栏你将学习到以下内容&#xff1a; 1&#xff09;音视频的解封装、解码&#xff1b; 2&#xff09;Qtopengl如何渲染视频&#…

【设计数据密集型应用】复制

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;阿里淘天Java开发工程师&#xff0c;CSDN博客专家&#x1f4d5;系列专栏&#xff1a;Spring源码、Netty源码、Kafka源码、JUC源码、dubbo源码系列&#x1f525;如果感觉博主的文章还不错的话…

Pycharm+Selenium WebdriverPython自动化测试

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Windows下CMake使用PCL提示全局作用域没有_open等文件读写函数

表现 解决办法 在导入PCL之前导入Windows SDK相关头文件: #if _WIN32 #include <corecrt_io.h> #endif

Activating More Pixels in Image SuperResolution Transformer

摘要 基于 Transformer 的方法在低级别视觉任务中表现出了令人印象深刻的性能&#xff0c;例如图像超分辨率。然而&#xff0c;我们通过归因分析发现&#xff0c;这些网络只能利用有限的输入信息空间范围。这意味着transformer 的潜力在现有网络中仍未得到充分利用。为了激活更…

2024年最新阿里云服务器地域选择方法,以及可用区说明

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

Qt 绘制中的视口(setViewport)和窗口(setWindow)

重点 &#xff1a; 1.绘制&#xff08;QPainter&#xff09;可以设置视口&#xff0c;视口下设置窗口&#xff0c;而绘制的构件是以窗口为坐标系进行绘画。 2.先根据绘图设备的物理坐标系的矩形位置&#xff0c;设置视图视口setViewport&#xff0c;然后在以视口为区域去设置…

vue基础教程(4)——深入理解vue项目各目录

博主个人微信小程序已经上线&#xff1a;【中二少年工具箱】。欢迎搜索试用 正文开始 专栏简介1. 总览2. node_modules3.public4.src5.assets6.components7.router8.stores9.views10.App.vue11.main.js12.index.html 专栏简介 本系列文章由浅入深&#xff0c;从基础知识到实战…

【开源物联网平台】使用MQTT.fx模拟设备接入FastBee物联网平台

​&#x1f308; 个人主页&#xff1a;帐篷Li &#x1f525; 系列专栏&#xff1a;FastBee物联网开源项目 &#x1f4aa;&#x1f3fb; 专注于简单&#xff0c;易用&#xff0c;可拓展&#xff0c;低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 创建产品&#xff…

HTTP Cookie 你了解多少?

Cookie是什么&#xff1f; 先给大家举个例子&#xff0c;F12 打开浏览器的页面之后&#xff0c;我们能在 Response Headers 的字段里面看到一个header 叫做 Set-Cookie&#xff0c;如下所示 图中包含的 Set-Cookie 为 Set-Cookie:uuid_tt_dd10_20293537580-1709432565344-232…

【C++】string类的基础操作

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. 基本概述 2. string类对象的常见构造 3. string类对象的容量操作 4. string类对象的访问及遍历操作 5. 迭代器 6.…