zoukankan      html  css  js  c++  java
  • AcWing 837. 连通块中点的数量

    题目传送门

    一、理解与感悟

    并查集+附加信息,附加信息为家族中成员的数量,需要一个额外的数组(s[N])记录以结点(i)为根的的家族成员数量。

    与最祼并查集的区别:

    • 初始化时需要将(s[i]=1)

    • 合并时,需要(s[find(b)]+ =s[find(a)])

    • 查询时:(s[find(a)])

    二、实现代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 100010;
    
    int n, m;
    int p[N];     //爸爸数组
    int s[N];    //每一个集合中点的数量
    
    //递归查找父节点
    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int main() {
        //优化输入
        ios::sync_with_stdio(false);
        cin >> n >> m;
    
        //并查集初始化
        for (int i = 1; i <= n; i++) {
            p[i] = i;
            s[i] = 1; //每个家族的成员数:1
        }
    
        while (m--) {
            string op;
            int a, b;
            cin >> op;
            if (op[0] == 'C') {
                cin >> a >> b;
                //如果a和b已经在同一个集合里了,那么就不需要进行处理了
                if (find(a) == find(b)) continue;
                //如果a和b不在同一个集合中
                s[find(b)] += s[find(a)];//更新族长记录的家族人员数量
                p[find(a)] = find(b);    //实现两个集合的合并
            } else if (op[1] == '1') {
                cin >> a >> b;
                if (find(a) == find(b)) puts("Yes"); // 两个节点在一个集合里
                else puts("No");    //不在一个集合里
            } else {
                //查询个数
                cin >> a;
                printf("%d
    ", s[find(a)]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    伍佰《突然的自我》
    .NET常见ORM框架
    并发和压测工具
    底层源码调试工具
    c 冒泡排序
    c 指定范围的质数
    c 筛法列举质数
    c 牛顿法求方程近似解
    c 二分法求方程近似解
    css选择器 及其权重
  • 原文地址:https://www.cnblogs.com/littlehb/p/15268351.html
Copyright © 2011-2022 走看看