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

数据结构--并查集

一、概述

1、定义:并查集是一种树型的数据结构

2、应用:用于处理不相交的集合的合并和查询。

二、操作及实现

1、查询:找到自己的老大

int find(int x)
{while(f[x]!=x)//如果自己的老大不是自己说明老大另有其人{x=f[x];//接着往下找老大}return x;//找到了老大
}

2、合并:合并成一个团伙

void join(int x,int y)
{int fx=find[x],fy=find[y];//找到两个人各自的老大if(fx!=fy)//如果两个人的老大不一样说明不是一个团伙{f[fx]=fy;//要合并成一个团伙,只能有一个老大,所以说其中一个老大要认另一个老大做新老大。}
}

3、路径压缩:(优化find函数)

如果树的深度过深,查询起来会相当耗时,所以说要减短树的深度。

可以将查询点x到根节点(也就是老大)的途径的点的父节点都设成为根节点,会大大降低查询的难度。

缺点是:只有当找到老大时,才能进行路径压缩,所以每个团体第一次的查询是没有什么优化的,之后才会生效。

int find(int x)//路径压缩 
{if(f[x]==x)return x;//如果自己的老大是自己输出return f[x]=find(f[x]);//如果不是,继续找老大,并且把自己的父节点设为老大
}

三、模板和例题

1、模板

洛谷P3367

https://www.luogu.com.cn/problem/P3367#submithttps://www.luogu.com.cn/problem/P3367#submit

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int f[N],a,b,c;
int find(int k)
{//路径压缩 if(f[k]==k)return k;return f[k]=find(f[k]);
}
int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++){f[i]=i;//初始化老大为自己 }for(int i=1;i<=m;i++){cin>>a>>b>>c;if(a==1){f[find(b)]=find(c);//合并  c所在组赢了b所在组 }else{if(find(b)==find(c))//检查老大是否相同 {cout<<"Y"<<endl;}else{cout<<"N"<<endl;}}}return 0;
} 

2、acwing 837、连通块中点的数量

https://www.acwing.com/problem/content/839/

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,f[N],cnt[N];
int find(int x)//不能用路径压缩因为那样的话就没办法统计连通快的数量了
{if (f[x] != x) f[x] = find(f[x]);return f[x];
}
void join(int x,int y)
{int fx=find(x),fy=find(y);if(fx!=fy){f[fx]=fy;}
}
int main()
{cin>>n>>m;for(int i=1;i<=n;i++){f[i]=i;cnt[i]=1;}while(m--){string flag;cin>>flag;int a,b;if(flag=="C"){cin>>a>>b;if(find(a)==find(b))continue;cnt[find(b)]+=cnt[find(a)];//先加连通块数量,否则先操作集合的话会导致重叠。而且要给新老大加,不能加错join(a,b);}else if(flag=="Q1"){cin>>a>>b;if(find(a)==find(b)){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}}else{cin>>a;cout<<cnt[find(a)]<<endl;}}return 0;
}

3、acwing 240食物链

//把食物环拆成食物链,用某节点到根节点的距离%3的余数来表示各节点之间的关系。
/*
余1:吃根节点
余2:被根节点吃
余0:同类
*/
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
int f[N],d[N];
int n,m;
int find(int x)
{if(f[x]!=x)//自己不是根节点{int t=find(f[x]);//先压缩路径使除x外的所有上级都指向根节点并记录根节点是谁d[x]+=d[f[x]];//到根节点的距离更新为x到其父节点的距离+父节点到根节点的距离f[x]=t;//再让x指向根节点}return f[x];
}
int main()
{cin>>n>>m;for(int i=1;i<=n;i++){f[i]=i;}int res=0;while(m--){int t,x,y;cin>>t>>x>>y;if(x>n||y>n){res++;continue;}int fx=find(x),fy=find(y);if(t==1)//同类{//在同一集合中if(fx==fy&&(d[x]-d[y])%3)res++;//两者%3不相等,说明不是同一类,谎话++else if(fx!=fy)//不在同一集合中,先到者为真{f[fx]=fy;//合并集合,让其中一个老大认另一个人做老大d[fx]=d[y]-d[x];//因为同类,所以(d[x]+d[fx]-d[y])%3==0}}//同上else{if(fx==fy&&(d[x]-d[y]-1)%3)res++;else if(fx!=fy){f[fx]=fy;d[fx]=d[y]+1-d[x];}}}cout<<res<<endl;return 0;
}

http://www.dtcms.com/a/529610.html

相关文章:

  • 简约创意网页设计seo还能赚钱吗
  • 本地用织梦做网站免费的wordpress企业模板
  • 苏州建设工程招标官方网站html网页制作心得体会
  • 公司做卖网站有前景吗域名对网站排名的影响
  • AI编程项目开发手册
  • 数据结构(HS)
  • 网站的相对路径上海域名网站吗
  • 电商网站的建设步骤黑龙江新闻联播历年片头
  • 营销型网站建设论坛网站建设公司能信吗
  • 展示型网站怎么做php做网站好吗
  • 网站开发方案及报价单调用别人网站的数据库
  • 个人网站开发报告莆田网站建设模板
  • 小规模开普票网站建设几个点织梦网站修改首页图片
  • 岳阳网站设计改版关键词有哪几种
  • wordpress网站会员太多wordpress设置文章
  • 如何开发微信微网站连云港企业网站制作
  • 公园网站建设方案 ppt模板广告互联网推广
  • 深入理解 Vue Router:底层原理与不同模式区别
  • 给企业做网站用什么程序深圳市官网网站建设报价
  • docker新手教程
  • 2025年主流大模型全景对比:Grok、Claude、ChatGPT与Gemini的战场
  • Spring Boot3零基础教程,SpringApplication 自定义 banner,笔记54
  • 做erp系统的网站网站调研方法有哪些内容
  • 做网站页面视频教学外贸网站建设智能建站
  • 多张图做网站背景wordpress后台翻译
  • 网站建设与维护本科教材中企动力做什么的
  • Spring LTW:类加载时织入全解析
  • 设计君网站wordpress的中文插件安装教程
  • 好口碑的网站制作安装价格世界足球排名
  • 网站开发环境vs2015是什么动漫设计与制作工资多少