并查集

简介: 文章目录前言一、例题,代码1.AcWing 836. 合并集合本题分析AC代码2.AcWing 837. 连通块中点的数量关于本题AC代码3.AcWing 240. 食物链关于本题AC代码二、时间复杂度

文章目录

前言

一、例题,代码

1.AcWing 836. 合并集合

本题分析

AC代码

2.AcWing 837. 连通块中点的数量

关于本题

AC代码

3.AcWing 240. 食物链

关于本题

AC代码

二、时间复杂度


前言

复习acwing算法基础课的内容,本篇为讲解基础算法:并查集,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。


一、例题,代码

1.AcWing 836. 并集

本题链接:合并集合

本博客给出本题的截图:

image.png

本题分析

如何合并两个集合:让它们的父节点相等


刚开始对于每一个点都是一个单独的集合

数组p代表着父节点,例如p[i]的值就是i的父节点的值

p数组的初始化p[i] = i;,如何合并两个集合呢?例如合并3和5这两个数所在的集合

那么一开始p[3] = 3, p[5] = 5,我们令p[3] = p[5] = 5,这一步的操作是让3的父节点指向5,即让5是3的父节点,我们写成p[5] = p[3] = 3也是可以的,二者没有本质的差别


那么如果我们紧接着想让2和3所在的集合进行合并,我们知道了现在3和5是在一个集合的,并且3的父节点是5,那么我们执行p[2] = p[find(3)],find(x)函数为查找x的父节点,执行完这个操作我们可以让2的父节点也指向5,从而达到集合合并的目的


find函数:我们查找p[x]和x是否相等,因为我们一开始都是让p[i] = i;,如果不相等,证明该点和别的集合进行了合并,那么我们就去继续寻找该点的父节点即p[x] = find(p[x].


AC代码

#include <cstdio>
using namespace std;
const int N = 100010;
int p[N];
int find(int x)
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) p[i] = i;
    while (m -- )
    {
        char op[2];
        scanf("%s", op);
        int a, b;
        scanf("%d%d", &a, &b);
        if (op[0] == 'M') p[find(a)] = find(b);
        else
            if (p[find(a)] == find(b)) puts("Yes");
            else puts("No");
    }
    return 0;
}

2.AcWing 837. 连通块中点的数量

本题链接:AcWing 837. 连通块中点的数量

本博客给出本题截图:

image.png

关于本题

相较于上一个题,我们还需要多维护一个cnt数组,因为每一个数一开始都是一个集合,所以每个集合的初始值为1,即cnt[i] = 1;

AC代码

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int p[N], cnt[N];
int find(int x)
{
    if (p[x] != x) p[x] = find(p[x]);
    else return p[x];
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ )
    {
        p[i] = i;
        cnt[i] = 1;
    }
    while (m -- )
    {
        string op;
        cin >> op;
        if (op == "C")
        {
            int a, b;
            scanf("%d%d", &a, &b);
            if (find(a) != find(b))
            {
                cnt[find(b)] += cnt[find(a)];
                p[find(a)] = find(b);
            }
        }
        else if (op == "Q1")
        {
            int a, b;
            scanf("%d%d", &a, &b);
            if (p[find(a)] == p[find(b)]) puts("Yes");
            else puts("No");
        }
        else
        {
            int x;
            scanf("%d", &x);
            printf("%d\n", cnt[find(x)]);
        }
    }
    return 0;
}

3.AcWing 240. 食物链

本题链接:AcWing 240. 食物链

本博客给出本题截图:

image.png

image.png

关于本题

分析过程有点复杂,文字性语言不好说清,未来会放一个文字版解释或一个视频讲解,先鸽

若有视频讲解,链接为(先鸽)

AC代码

#include <cstdio>
using namespace std;
const int N = 50010;
int p[N], d[N];
int find(int x)
{
    if (p[x] != x)
    {
        int t = find(p[x]);
        d[x] += d[p[x]];
        p[x] = t;
    }
    return p[x];
}
int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i ++ ) p[i] = i;
    int res = 0;
    while (k -- )
    {
        int x, y, q;
        scanf("%d%d%d", &q, &x, &y);
        int px = find(x), py = find(y);
        if (x > n || y > n) res ++;
        else 
        {
            if (q == 1)
            {
                if (px == py && (d[x] - d[y]) % 3) res ++;
                else if (px != py)
                {
                    p[px] = py;
                    d[px] = d[y] - d[x];
                }
            }
            else
            {
                if (px == py && (d[x] - d[y] - 1) % 3) res ++;
                else if (px != py)
                {
                    p[px] = py;
                    d[px] = d[y] + 1 - d[x];
                }
            }
        }
    }
    printf("%d", res);
    return 0;
}

二、时间复杂度

关于并查集算法的时间复杂度以及证明,后续会给出详细的说明以及证明过程,目前先鸽了。


目录
相关文章
|
4天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1313 3
|
4天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
654 3
|
5天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
|
11天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
761 5
|
8天前
|
物联网 API UED
Qwen-Image-Edit-2511来啦!角色一致性再提升,LoRA能力内置
Qwen-Image-Edit-2511发布!提升角色与多人合照一致性,集成Lora打光、新视角生成,增强工业设计与几何推理能力。已开源,支持魔搭、QwenChat免费体验,本地部署可获最佳效果。
464 3