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

并查集的原理+例题

并查集的原理+例题

  • 1. 并查集原理
  • 2. 例题
    • 基础实验4-2.8 部落

1. 并查集原理

在这里插入图片描述

如图,在三个圈中,分别有数字
1 2 3 4
4 6 7 8
11 12

我们规定,每个圈中都有自己的大佬,并且只有1个
所以,
2 3 4 跟随的就是1
6 7 8 跟随的就是4
12 跟随的就是 11

但是我们发现,4在圈1中也出现了,那么既然4在圈1中跟随的是 数字1
那么所以 6 7 8也就跟随的是 数字1

既然如此了,那么图中,其实就只剩 两个圈了,在这里插入图片描述
并查集的作用就是 把 2 3 4 6 7 8 都跟随到 数字1
12跟随到 数字11

那么怎么做到 当我们得到数字 2 3 4 6 7 8就能得到 他们的大佬数字 1呢?

方法如下:
在这里插入图片描述
我们定义一个数组,使角标为 2 3 4 5 6 7 8的数组值 都为 1
这样我们就能得到他们的大佬是 1.

但是,最开始的时候
在这里插入图片描述
6 7 8的大哥其实是 4
那么我们怎么 使得 6 7 8的大哥改成为1的呢
其实那么我就把 6 7 8的大哥拿出来,看一看,大哥的数组值是不是自己的角标,如果是,那么说明大哥没有大哥的大哥,也就是大哥把自己作为大哥,那么怎么拿出大哥的数组值呢?

我们把整个数组名 记作 a
那么 角标6的大哥 的角标也就是 a[6](也就是4) 那么a[a[6]] 就表示6的大哥角标,我们判断 大哥的角标是否等于 自身值 a[a[6]] 4,如果不等于,那么我们再去找 a【a[a[6]]】即可。

综上就是这样一个代码

int f(int a)
{
    if (pre[a] != a) pre[a] = f(pre[a]);
    return pre[a];
}

注意:这是一个递归函数,递归 pre[a] = f(pre[a]);

补充讲解一下:递归函数,什么叫做递归函数
递:就是可以一直往下传递(也就是自己调用自己 如f(pre[a]))
归:就是返回值,有接收 pre[a] = f(pre[a])(这样才能有良性的递归)
如果 我们只写成 f(pre[a]) 那么这个函数的返回值,没有数据进行接收,则不能真正递归

当我们已经会找到一个数据的老大了,那么我们还需要把两个数据归并到一个老大中,比如a,b
我们要把b归并到a的圈子里,怎么做呢?
其实我们只需要找到a的老大,或者a本身就是老大
然后 我们找到b的老大,或者b就是自己的老大
最后 我们让 b的老大 等于 a的老大
这样一来,我们就把b的圈子 全部 归到 a 的圈子里了
代码如下:

void merge(int father, int child)
{
    int mm = father, nn = child;
    if (f(father) != father)
        mm = f(father);
    if (f(father) != child)
        nn = f(child);
    pre[nn] = mm;
}

int f(int a)
{
    if (pre[a] != a) pre[a] = f(pre[a]);
    return pre[a];
}

到此为止,我们就完成了并查集的原理代码

2. 例题

基础实验4-2.8 部落

原题链接

在这里插入图片描述

#include<iostream>
using namespace std;

int pre[10001], e[10001];

int f(int a)
{
    if (pre[a] != a) pre[a] = f(pre[a]);
    return pre[a];
}

void merge(int father, int child)
{
    int mm = father, nn = child;
    if (f(father) != father)
        mm = f(father);
    if (f(father) != child)
        nn = f(child);
    pre[nn] = mm;
}

int main()
{
    for (int i = 1; i <= 10001; i++)
        pre[i] = i;
    int max = 0;
    int N;
    cin >> N;
    while (N--)
    {
        int n;
        cin >> n;
        int p = 0, q = 0;
        for (int i = 1; i <= n; i++)
        {
            if (i == 1)
            {
                cin >> q;
                if (q > max) max = q;
            }
            else
            {
                cin >> p;
                if (p > max) max = p;
                merge(q, p);
                q = p;
            }
        }
    }

    for (int i = 1; i <= max; i++)
    {
        e[f(i)]++;
    }
    int g = 0;
    for (int i = 1; i <= max; i++)
    {
        if (e[i])
            g++;
        //cout << f(i) <<endl;
    }
 cout << max << ' ' << g << endl;
    int q,p;        
   cin >> N;
    while(N--)
    {
        
         cin >> q >> p;
         if(f(p) == f(q))
            cout << 'Y' << endl;
        else
             cout << 'N' << endl;
     }
  
    return 0;
}

相关文章:

  • 同样是Java程序员,年薪10W和35W的差别在哪?
  • 阿里为了双十一,整理亿级JVM性能优化文档,竟被GitHub“抢开”
  • 反转链表I和II(迭代和递归)
  • (附源码)ssm教材管理系统 毕业设计 011229
  • 系统运维管理小记
  • 最全解决方式java.net.BindException Address already in use JVM_Bind
  • Java配置40-配置ELK+Kafka集成
  • 《论文阅读》MOJITALK: Generating Emotional Responses at Scale
  • 统计字符出现次数(区分大小写和不区分大小写两种方式)
  • Java开发之高并发必备篇(二)——线程为什么会不安全?
  • 低代码技术研究路径解读|低代码的产生不是偶然,是数字技术发展的必然
  • OPT华东产业园封顶,机器视觉产业版图再扩大!
  • 多肽RGD修饰乳清白蛋白/肌白蛋白/豆清白蛋白/蓖麻蛋白/豌豆白蛋白1b ( PA1b)纳米粒(实验原理)
  • 基于Mybatis-Plus扩展批量插入或更新InsertOrUpdateBath
  • LeetCode·701.二叉搜索树中的插入操作·递归
  • ----------
  • Android开源项目规范总结
  • C++入门教程(10):for 语句
  • Electron入门介绍
  • Git初体验
  • JAVA多线程机制解析-volatilesynchronized
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • oldjun 检测网站的经验
  • PAT A1050
  • Promise初体验
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • C# - 为值类型重定义相等性
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (js)循环条件满足时终止循环
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (一)VirtualBox安装增强功能
  • (转)母版页和相对路径
  • (转)我也是一只IT小小鸟
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • . Flume面试题
  • .Net 4.0并行库实用性演练
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .net 无限分类
  • .NET轻量级ORM组件Dapper葵花宝典
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——
  • [Angular] 笔记 18:Angular Router
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [CISCN 2019华东南]Web11
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [CSS]CSS 字体属性
  • [Latex学习笔记]数学公式基本命令