首页 > 其他分享 >并查集

并查集

时间:2023-04-05 17:35:13浏览次数:22  
标签:Q1 输出 int 查集 cin find op

并查集

合并集合

一共有 n 个数,编号是 1∼n,最开始每个数各自在一个集合中。

现在要进行 m 个操作,操作共有两种:

  1. M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
  2. Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 M a bQ a b 中的一种。

输出格式

对于每个询问指令 Q a b,都要输出一个结果,如果 a 和 b 在同一集合内,则输出 Yes,否则输出 No

每个结果占一行。

数据范围

\(1≤n,m≤10^5\)

输入样例:

4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4

输出样例:

Yes
No
Yes

AC代码

#include <iostream>

using namespace std;

const int N = 1e5 + 10;
int p[N];
int m, n;

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


int main(){
    cin >> n >> m;
    for(int i = 0; i < n; i ++){
        p[i] = i;
    }
    while (m --) {
        char op;
        int a, b;
        cin >> op >> a >> b;
        if(op == 'M') {
            p[find(a)] = find(b);
        }else {
            if(find(a) == find(b)) {
                cout << "Yes" << endl;
            }else {
                cout << "No" << endl;
            }
        }

    }
}

连通块中点的数量

给定一个包含 n 个点(编号为 1∼n)的无向图,初始时图中没有边。

现在要进行 m 个操作,操作共有三种:

  1. C a b,在点 a 和点 b 之间连一条边,a 和 b 可能相等;
  2. Q1 a b,询问点 a 和点 b 是否在同一个连通块中,a 和 b 可能相等;
  3. Q2 a,询问点 a 所在连通块中点的数量;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 C a bQ1 a bQ2 a 中的一种。

输出格式

对于每个询问指令 Q1 a b,如果 a 和 b 在同一个连通块中,则输出 Yes,否则输出 No

对于每个询问指令 Q2 a,输出一个整数表示点 a 所在连通块中点的数量

每个结果占一行。

数据范围

\(1≤n,m≤10^5\)

输入样例:

5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5

输出样例:

Yes
2
3

AC代码

#include <iostream>
#include <string.h>
using namespace std;

const int N = 1e5 + 10;
int p[N], s[N];
int m, n;

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


int main(){
    cin >> n >> m;
    for(int i = 0; i < n; i ++){
        p[i] = i;
        s[i] = 1;
    }
    while (m --) {
        char op[3];
        
        cin >> op;
        if(!strcmp(op, "C")) 
        {
            int a, b;
            cin >> a >> b;
            if(find(a) != find(b)){
                s[find(b)] += s[find(a)];  
            }
            p[find(a)] = find(b);
        }
        else if(!strcmp(op, "Q1"))
        {
            int a, b;
            cin >> a >> b;
            if(find(a) == find(b)) 
            {
                cout << "Yes" << endl;
            }
            else 
            {
                cout << "No" << endl;
            }    
        } else {
            int a;
            cin >> a;
            cout << s[find(a)] << endl;
        }
        
    }
}

标签:Q1,输出,int,查集,cin,find,op
From: https://www.cnblogs.com/wojiuyishui/p/17289937.html

相关文章

  • 最长连续序列(并查集、数组)、复原 IP 地址(字符串、回溯)、删除链表的倒数第 N 个结
    最长连续序列(并查集、数组)给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为O(n)__的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4......
  • 并查集(nuist LevOJ P1648)
    一、并查集1.1并查集简介并查集是一种简单的集合表示,是一种树形数据结构,可处理不相交集合的合并及查询问题。并查集可求联动分支数。并查集存储:现有9个元素0~9,建立一个数组(初始化元素为-1),用数组下标表示元素,数组中的数据表示根节点的下标。数组中数据为负数时表示它是根节点......
  • 算法笔记之并查集
    一、并查集的定义并查集是一种树型的数据结构,用于处理一些不相交集合(disjointsets)的合并及查询问题。常常在使用中以森林来表示。并查集,顾名思义,支持以下两种操作操作:并(Union):把两个不相交的集合合并为一个集合。查(Find):查询两个元素是否在同一个集合中。二、并查......
  • The Suspects POJ - 1611 (并查集)
    题意:n个学生分属m个团体,一个学生可以属于多个团体。一个学生疑似患病则它所属的整个团体都疑似患病。已知0号学生疑似患病,以及每个团体都由哪些学生构成,求一共多少个学生疑似患病。分析:维护一个并查集,查询与0在同一集合的元素数量。#include<iostream>#include<cstdio>using......
  • 天梯赛练习题 L3-003 社交集群 (简单并查集)
    https://pintia.cn/problem-sets/994805046380707840/exam/problems/994805053141925888题目大意:当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到......
  • 并查集
    并查集主要包括初始化、寻根以及合并三个操作。例如a、b、c、d、e,初始化他们的祖先为本身。寻根操作:intfind_root(intx){//非路径压缩returnx==s[x]?x:finde_r......
  • How Many Tables HDU - 1213(并查集/连通块数量)
    题意:朋友的朋友是朋友如果A认识B,B认识C,那么ABC三个人就可以坐在同一张桌子上但如果A认识B,C认识D,那我们就默认AB和CD不认识,需要准备两张桌子现在我们需要你计算出,我们一......
  • 2023-03-23_并查集
    并查集两个点之间在树或图中是否连通的问题。1什么是并查集?连接问题网络中节点间的连接状态数学中的集合类实现连接问题与路径问题:解决路径问题便一定可以解......
  • 并查集模板
    并查集(Union(并),Find(查),Set(集))一般用树的形式保存集合,但是是用数组模拟的树对于并查集树上的所有点,只有根结点是p[x]=x的,其他的p[x]都是父结点那么就可以通过whil......
  • 并查集拓展
    上一期由于上一期过水,只讲了一点点序列的问题,然而在乱逛看题解的时候,发现其实并查集能做到的远远不止图论与有限步骤序列问题,今天就从一(不会讲模板的)开始来记录一下并查集......