[AcWing算法提高课]之 高阶数据结构 并查集(C++题解)

本文详细介绍了并查集的基本框架,包括初始化、路径压缩的find函数以及不带权重和带权重的并查集应用过程。通过具体例题展示了并查集在处理亲戚关系、格子游戏、搭配购买和程序自动分析等问题中的应用。此外,还提及了带权重并查集在解决"银河英雄传说"问题中的核心思路。
摘要由CSDN通过智能技术生成

目录

(一)并查集的框架

(1)初始化并查集

(2)find函数实现路径压缩

(3)并查集的应用过程

(二)不带权重并查集例题

(1)亲戚

(2)格子游戏

(3)搭配购买

(4)程序自动分析

(三)带权重并查集(待补充)

(1)银河英雄传说


(一)并查集的框架

(1)初始化并查集

const int N=1e5+10;
int p[N];
int Size[N];
int d[N];//x->其祖宗节点的距离不用初始化:全局变量默认为 0

void init()
{
    for(int i=1;i<=N;i++)
    {
        p[i]=i;//每个节点的初始祖宗节点就是自己
        Size[i]=1;//每个节点的初始子长度为1(即自己)
    }
}

(2)find函数实现路径压缩

int find_without_weight(int x)
{
    if(x!=p[x]) p[x]=find_without_weight(p[x]);
    return p[x];
}

int find_with_weight(int x)
{
    if(p[x]!=x)
    {
        int root=find_with_weight(p[x]);//找根
        d[x]+=d[p[x]];//d[x]到根节点的距离=x->父节点的距离+父节点到根节点的距离
        p[x]=root;//记录x的根
    }
    return p[x];
}

(3)并查集的应用过程

(1)根据题目所求,将所给的点进行拼接,即:
void test_without_weight()//不带权重
{
    int n;
    cin>>n;//执行n次 合并操作

    while(n--)
    {
        int a,b;//要操作的两个节点
        cin>>a>>b;
        int pa=find_without_weight(a);//寻找它们的各自的祖宗
        int pb=find_without_weight(b);

        p[pa]=pb;//将a节点的祖宗节点 连接到b的祖宗节点
    }
}

void test_with_weight()//带权重
{
    int n;
    cin>>n;

    while(n--)
    {
        int a,b;
        cin>>a>>b;

        int pa=find_with_weight(a);
        int pb=find_with_weight(b);

        d[pa]=Size[pb];//pa->pb的距离为 Size[pb]
        Size[pb]+=Size[pa];//合并:pb为根的 战舰列边长
        p[pa]=pb;
    }
}
(2)查询过程:
void query()
{
    int a,b;
    cin>>a>>b;

    int pa=find_without_weight(a);
    int pb=find_without_weight(b);

    if(pa!=pb) puts("Write what you want here");
    else puts("Write what you want here");
}

完整过程:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=1e5+10;
int p[N];
int Size[N];
int d[N];//x->其祖宗节点的距离不用初始化:全局变量默认为 0

void init()
{
    for(int i=1;i<=N;i++)
    {
        p[i]=i;//每个节点的初始祖宗节点就是自己
        Size[i]=1;//每个节点的初始子长度为1(即自己)
    }
}

int find_without_weight(int x)
{
    if(x!=p[x]) p[x]=find_without_weight(p[x]);
    return p[x];
}

int find_with_weight(int x)
{
    if(p[x]!=x)
    {
        int root=find_with_weight(p[x]);//找根
        d[x]+=d[p[x]];//d[x]到根节点的距离=x->父节点的距离+父节点到根节点的距离
        p[x]=root;//记录x的根
    }
    return p[x];
}

void test_without_weight()
{
    int n;
    cin>>n;//执行n次 合并操作

    while(n--)
    {
        int a,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值