透过一张图 彻底明白并查集维护与祖宗结点关系的方法

算法详解

在这里插入图片描述

238.银河英雄传说(维护与祖宗结点的距离)

在这里插入图片描述

/**
 *    @Author: Wilson79
 *    @Datetime: 2019年12月22日 星期日 11:43:37
 *    @Filename: 238.银河英雄传说.cpp
 */

// 用size去维护每个连通块的个数,d[x]表示x到当前祖宗结点的距离,d[x]在find一次后会更新
// 每次把size加到pa上,这样整个pa连通块上的点的d[i],之后更新时都会加上这个size
    
#include <iostream>

using namespace std;

const int N = 30010;

int p[N], d[N], size[N];
int a, b;

int find(int x) {
    if (p[x] != x) {
        int root = find(p[x]); // 递归到底
        d[x] += d[p[x]]; // 从底往回,更新距离
        p[x] = root; // 压缩路径
    }
    return p[x];
}


int main() {
    int T;
    scanf("%d", &T);

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

    while(T --) {
        char op[2]; // 用scanf读单个字符的巧妙写法
        scanf("%s%d%d", op, &a, &b);

        if (op[0] == 'M') {
            int pa = find(a), pb = find(b);
            d[pa] += size[pb]; // 把size加到pa结点即可,这样原pa连通块上的距离在之后find时都会加上这个size
            size[pb] += size[pa];
            p[pa] = pb;
        } else {
            int pa = find(a), pb = find(b);
            // 必须find一次,才能把d[a],d[b]更新到最新
            if (pa != pb) cout << "-1" << endl;
            else {
                cout << max(abs(d[a] - d[b]) - 1, 0) << endl;
            }
        }
    }


    return 0;
}
并查集维护祖宗距离是指在并查集的数据结构中,除了记录每个元素的父节点外,还记录了每个元素到其祖宗节点的距离。这样可以在查找祖宗节点的同时,更新每个元素到祖宗节点的距离。这个功能可以通过路径压缩来实现。路径压缩是指在查找祖宗节点的过程中,将路径上的每个节点的父节点直接指向祖宗节点,从而减少后续查找的时间复杂度。在路径压缩的过程中,还可以同时更新每个节点到祖宗节点的距离。这样,在后续的操作中,可以直接通过查找元素的祖宗节点来获取元素到祖宗节点的距离,而无需再次进行计算。引用\[1\]中的代码是一个实现路径压缩的示例,其中的d数组就是用来记录每个元素到祖宗节点的距离。引用\[2\]和引用\[3\]中也提到了路径压缩的概念和实现方式。 #### 引用[.reference_title] - *1* [AcWing 238. 银河英雄传说--(维护size和到祖宗节点距离)带权并查集](https://blog.csdn.net/qq_45748404/article/details/117967117)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [算法基础课—数据结构(六) 并查集](https://blog.csdn.net/Yttttttttttttttt/article/details/117067020)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捡起一束光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值