当前位置: 首页 > news >正文

算法竞赛备赛——【数据结构】并查集

并查集

普通并查集

注意根据数据大小来开int 或者 long long 否则容易MLE

树的存储结构 双亲表示法——数组 孩子表示法 孩子兄弟表示法

P3367 【模板】并查集 - 洛谷

#include <bits/stdc++.h>
using ll=long long;
using namespace std;
const int N=2e5+5; 

int fa[N];
int n,m;

int find(int x){
	if(x==fa[x])
		return x;
	else return fa[x]=find(fa[x]);
} 
 
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;++i){
		fa[i]=i;
	}
	for(int i=0;i<m;++i){
		int z,x,y;cin>>z>>x>>y;
		if(z==1){
			//合并
			int fx=find(x);
			int fy=find(y);
			fa[fx]=fy;
		}else{
			//查询 
			int fx=find(x);
			int fy=find(y);
			if(fx==fy) cout<<"Y"<<endl;
			else cout<<"N"<<endl;
		}
	}
	return 0;
}

种类并查集

扩展域并查集 可描述敌对关系

敌人 朋友 没关系 扩展为2n

天敌 同类 猎物 没关系 扩展为3n

[P1525 NOIP 2010 提高组] 关押罪犯 - 洛谷

#include <bits/stdc++.h>
using ll=long long;
using namespace std;
const int N=2e4+2; 

int f[2*N];
struct enemy{
	int a,b,c;
}e[100005];

bool cmp(enemy& e1,enemy& e2){
	return e1.c>e2.c; 
}

int find(int x){
	if(f[x]==x){
		return x;
	}
	else return f[x]=find(f[x]);
}

int main(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=2*n;++i){
		f[i]=i;
	}
	for(int i=1;i<=m;++i){
		cin>>e[i].a>>e[i].b>>e[i].c;
	}
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=m;i++){
		int fa=find(e[i].a);
		int fb=find(e[i].b); 
		int fad=find(e[i].a+n);
		int fbd=find(e[i].b+n);
		if(fa==fb){
			cout<<e[i].c;
			return 0;
		}
		f[fa]=fbd;
		f[fb]=fad;
	}
	cout<<0<<endl;
	return 0;
}

[P2024 NOI2001] 食物链 - 洛谷

#include <bits/stdc++.h>
using ll=long long;
using namespace std;
const int N=5e4+5; 

int f[3*N];

int find(int x){
	if(f[x]==x){
		return x;
	}
	else return f[x]=find(f[x]);
}

int main(){
	int n,k;cin>>n>>k;
	int ans=0;
	for(int i=1;i<=3*n;++i){
		f[i]=i;
	} 
	while(k--){
		int m,x,y;
		cin>>m>>x>>y;
		if(x>n||y>n||(m==2&&x==y)){
			ans++;
			continue;
		}
		int fx=find(x);//x同类 
		int fy=find(y);//y同类 
		int xenemy=find(x+n);//x天敌 
		int yenemy=find(y+n);//y天敌 
		int xeat=find(x+2*n);//x猎物 
		int yeat=find(y+2*n);//y猎物 
		if(m==1){
			if(xenemy==fy||yenemy==fx){
				ans++;
			}else{
				f[fx]=fy;
				f[xenemy]=yenemy;
				f[xeat]=yeat;		
			}
		}
		if(m==2){
			if(fx==fy||yeat==fx){
				ans++;	
			}else{
				f[fy]=xeat;
				f[yeat]=xenemy;
				f[yenemy]=fx;
			} 
		}
	}
	cout<<ans; 
	return 0;
}

相关文章:

  • Hexo + Fluid博客实现自定义图标
  • Verilog HDL 100道面试题及参考答案
  • 目前市场上,好用的校招系统是哪个?
  • 我与数学建模之启程
  • C/C++网络编程【1】----- 大纲
  • 【深度视觉】第十八章:YOLO系列1
  • Jetpack Room 使用与原理解析
  • Vue2 vs Vue3 生命周期全面对比:created 的进化与革新!!!
  • String数据结构之验证码实战
  • Unity3D仿星露谷物语开发32之地面属性决定角色动作
  • 【Django】教程-5-ModelForm增删改查+规则校验【正则+钩子函数】
  • 数据库表省市区分析
  • Kubernetes可视化面板——KubePi(Kubernetes Visualization Panel - kubepi)
  • Android BottomNavigationView 完全自定义指南:图标、文字颜色与选中状态
  • Outlook客户端无法连接到服务器,添加账户显示“无网络连接,请检查你的网络设置,然后重试。[2603]”
  • 优秀的 React 入门开源项目推荐
  • Redis 源码硬核解析系列专题 - 结语:从源码看Redis的设计哲学
  • Meta Llama 3:开启大语言模型新纪元
  • 美股恐惧贪婪指数监控
  • Kafka 实战指南:原理剖析与高并发场景设计模式
  • 做网站的财务需求/网站关键词优化推广哪家好
  • 石家庄网站建设电话咨询/互联网广告行业分析
  • 天津免费网站建站模板/友链网站
  • 网站开发人员 组织架构/长沙网站seo分析
  • 设计商业网站应该做到什么/网站seo优化排名
  • 乌鲁木齐市新市区建设局网站/宁波seo关键词排名优化