惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

faryou的博客

faryou的博客 faryou的博客 faryou的博客 faryou的博客 faryou的博客 faryou的博客-福建行小记 faryou的博客 faryou的博客 faryou的博客 faryou的博客 faryou的博客-夏令营小记 faryou的博客 faryou的博客 faryou的博客 faryou的博客-暑假阶段总结与展望 faryou的博客 faryou的博客 faryou的博客 faryou的博客 台风进行时 faryou的博客 limbo虚拟机初体验&安装Windows NT 4.0 faryou的博客 台风将来时 faryou的博客 faryou的博客 faryou的博客 faryou的博客 出租车上的对话 faryou的博客
【算法教程】【C/C++】并查集——程序设计思路与代码实现
作者: faryou · 2024-09-01 · via faryou的博客

前言
图论是算法中的一个重要内容,图的范围很广,包括二叉树、树、图等。今天我们来学习树的重要内容——并查集。

程序设计思路
并查集是一个森林(由一棵或多棵树组成的集)。我们可以利用其特性进行一些操作。
在并查集中,最重要的操作便是并和查。
并是指将两棵树合并为一棵。这很好进行,因为并查集里的每个数都有一个指针指向自己的父亲。
查找也不难,只需要一个递归程序,不断查找父亲的父亲,最后找到最老的祖先再返回(注意:并查集中最老的祖先的祖先是其自身)。
比较重要的是一个优化方案——路径压缩。由于查找是递归调用,故当要找的祖先过于遥远时,我们可以使用路径压缩,将一棵树中的全部非根节点的祖先直接设置为最老的祖先。路径压缩通常在执行查找命令时进行。

代码实现
下面通过并查集的模板题讲解其用法:
202408231724417005184545.png
这题要求我们模拟并查集的操作,直接上代码:

#include <bits/stdc++.h>
using namespace std;

int n,m,z[200005],x[200005],y[200005],bin[10005];//z、x、y如题意,bin为并查集中每个数的祖先(父亲)

int find(int a){//查找操作
    int x=a;
    if(bin[x]!=x) return bin[x]=find(bin[x]);//在查找的过程中路径压缩
    else return x;//当查到某个数的祖先是它自己时,说明找到了祖先,开始返回
}
void join(int b,int c){//并操作
    if(find(b)!=find(c)) bin[find(b)]=find(c);
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) bin[i]=i;
    for(int i=1;i<=m;i++) scanf("%d%d%d",&z[i],&x[i],&y[i]);
    for(int i=1;i<=m;i++){
        if(z[i]==1) join(x[i],y[i]);
        else{
            if(find(x[i])==find(y[i])) printf("Y\n");
            else printf("N\n");
        }
    }
    return 0;
}

这样,我们就较好的模拟了一个并查集。

结语
并查集是图论中较为简单的一科,只需要记下并、查两个操作就可以解决相关问题。我是faryou,再见!