一文看明白并查集

简介: 一文看明白并查集

什么是并查集


并查集本质就是集合。


  • 并查集可以进行集合合并的操作(并)
  • 并查集可以查找元素在哪个集合中(查)
  • 并查集维护的是一堆集合(集)

对于并查集我们需要知道两个信息

  • 元素的值
  • 集合的标号


用什么样的数据结构表示并查集?


我们能不能让一个数组存储每个节点的父节点,连成一棵树呢?


初始时每个节点都是一个单独的集合,父节点指向自己,

如果要合并两个集合,那么将a的父节点设为b,将a插入到b节点下充当子节点

那么如何判断是否是同一集合呢? 就看祖宗节点是否相同,如果相同则代表是同一集合


初始化:


1. 
int []p=new int[N];   //存储每个节点的父节点
2. for (int i = 1; i <=n; i++)  p[i]=i;


返回x的祖宗节点:


    public static int find(int x){
        if(p[x]!=x)  
      p[x]=find(p[x]); //将x的父亲置为x父亲的祖先节点,实现路径的压缩
        return p[x];
    }


find的功能是用于查找祖先节点,那么路径压缩又是怎么完成的


合并为同一集合:


p[find(a)] = find(b);


查找是否同一集合


find(a) == find(b)


如果想知道每一个集合的数量呢?


我们引入一个size集合,存储每个节点自己的数量+子孙节点的数量,

那么祖宗节点的size就是整个集合的数量,即size[find(a)]

初始化:


  for (int i = 1; i <=n; i++) {
            p[i]=i;
            size[i]=1;
   }


合并为同一集合:


1.  p[find(a)] = find(b);
2.  size[find(b)]+=size[find(a)]


给一个例题 连通块中点的数量


给定一个包含 n 个点(编号为 1∼n)的无向图,初始时图中没有边。


现在要进行 m个操作,操作共有三种:


C a b,在点 aa 和点 bb 之间连一条边,aa 和 bb 可能相等;


Q1 a b,询问点 aa 和点 bb 是否在同一个连通块中,aa 和 bb 可能相等;


Q2 a,询问点 aa 所在连通块中点的数量;


输入格式


输入样例:5 5C 1 2Q1 1 2Q2 1C 2 5Q2 5
输出样例:Yes23


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
    static int N=100010;
    static int []p=new int[N];   //存储每个节点的父节点
    static int []size=new int[N];  //查询根节点,得到整个集合数量
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String []s=br.readLine().split(" ");
        int n=Integer.parseInt(s[0]),m=Integer.parseInt(s[1]);
        for (int i = 1; i <=n; i++) {
            p[i]=i;
            size[i]=1;
        }
        while (m-->0){
            String []fir=br.readLine().split(" ");
            if("C".equals(fir[0])){  //集合合并
                int pa=find(Integer.parseInt(fir[1]));
                int pb=find(Integer.parseInt(fir[2]));
                if(pa!=pb){
                    p[pa]=pb;
                    size[pb]+=size[pa];
                }
            }else if("Q1".equals(fir[0])){
                int pa=find(Integer.parseInt(fir[1]));
                int pb=find(Integer.parseInt(fir[2]));
              if(pa==pb){
                  System.out.println("Yes");
              }else System.out.println("No");
            }else {
                int pa=find(Integer.parseInt(fir[1]));
                System.out.println(size[pa]);
            }
        }
    }
    //返回每个节点的父节点
    public static int find(int x){
        if(p[x]!=x)  p[x]=find(p[x]);
        return p[x];
    }
}
相关文章
|
芯片 异构计算 内存技术
关于SPI协议,看这一篇文章就够了!
关于SPI协议,看这一篇文章就够了!
2550 0
关于SPI协议,看这一篇文章就够了!
|
算法 JavaScript 大数据
高德地图 错误码说明 对照表
序号  infocode info返回值 状态描述 问题排查策略 1 10000 OK 请求正常 请求正常 2 10001 INVALID_USER_KEY key不正确或过期 开发者发起请求时,传入的key不正确或者过期  3 10002 SERVICE_NOT_AVAILABLE 没有权限使用相应的服务或者请求接口的路径拼写错误 1.开发者没有权限使用相应的服务,例如:开发者申请了WEB定位功能的key,却使用该key访问逆地理编码功能时,就会返回该错误。反之亦然。2.开发者请求接口的路径拼写错误。例如:正确的https://restapi.amap.com/v3/ip在程序中被拼装写了h
5469 0
|
10月前
|
存储 安全 API
电商API合规性:确保数据隐私与法规遵守
在数字化电商时代,API作为连接平台、商家与用户的关键枢纽,承载大量敏感数据。面对日益严格的数据隐私法规,如GDPR、CCPA和中国《个人信息保护法》,合规成为企业发展的核心挑战。本文探讨如何通过系统化方法保障电商API的数据安全与法规遵循,涵盖法规要点、技术实现与最佳实践,助力企业在合规基础上稳健发展。
477 0
|
10月前
|
网络协议 算法 网络架构
动态路由协议的分类
动态路由协议分为内部网关协议(IGP)和外部网关协议(EGP)。IGP用于自治系统(AS)内部,如RIP、OSPF、EIGRP、IS-IS,负责快速发现和计算最优路径;EGP如BGP用于不同AS之间,传递路由信息并避免环路。IGP关注收敛速度与路径计算,EGP侧重策略与大规模路由支持。两者共同构建互联网路由体系。
1300 0
|
人工智能 资源调度 API
AnythingLLM:34K Star!一键上传文件轻松打造个人知识库,构建只属于你的AI助手,附详细部署教程
AnythingLLM 是一个全栈应用程序,能够将文档、资源转换为上下文,支持多种大语言模型和向量数据库,提供智能聊天功能。
10108 76
|
机器学习/深度学习 人工智能 搜索推荐
AI时代下的个人发展之路:通过多栈变革实现跨越式成长
随着人工智能(AI)技术的飞速发展,企业和个人面临着前所未有的机遇和挑战。在AI时代,多栈变革成为推动企业和个人发展的关键。对企业而言,AI不仅促进了数据驱动的决策和智能自动化,还推动了产品创新和业务流程优化。而对于个人,AI的崛起提供了通过跨界学习、掌握多项技能及使用AI工具提升效率的机会。本文探讨了AI如何通过多栈变革推动企业和个人的全方位发展,同时也分析了面临的挑战与未来展望。在这个智能化、数据化的时代,只有不断学习与适应的企业和个人,才能抓住AI带来的机遇,迎接更加智能化的未来。
|
监控 安全 网络安全
100个网络安全中英文术语,太详细了!
【10月更文挑战第22天】
1517 0
100个网络安全中英文术语,太详细了!
|
存储 数据库 数据安全/隐私保护
如何选择云服务提供商?
【4月更文挑战第26天】如何选择云服务提供商?
569 3