合并集合(并查集)

简介: 合并集合(并查集)

并集

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

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

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

Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中;

输入格式

第一行输入整数 n 和 m。

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

输出格式

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

每个结果占一行。

数据范围

1≤n,m≤105

输入样例:

4 5

M 1 2

M 3 4

Q 1 2

Q 1 3

Q 3 4

输出样例:

Yes

No

Yes

提交代码

#include<iostream>
using namespace std;
const int N = 100010;
int n, m;
int p[N];
int find(int x)                 // 找到x的祖先节点
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
int main()
{
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) p[i] = i;
    while (m--)
    {
        char op;
        int a, b;
        scanf (" %c%d%d", &op, &a, &b);
        if (op == 'M') p[find(a)] = find(b);        // 让a的祖先节点指向b的祖先节点
        else
        {
            if (find(a) == find(b)) puts("Yes");
            else puts("No");
        }
    }
    return 0;
}
import java.io.*;
public class Main
{
    static int N = 100010;
    static int n, m;
    static int [] p = new int [N];
    static int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader (System.in));   
        String [] str = reader.readLine().split(" ");
        n = Integer.parseInt(str[0]);
        m = Integer.parseInt(str[1]);
        for (int i = 1; i <= n; ++ i) p[i] = i;
        while (m -- > 0)
        {
            String op;
            int a, b;
            str = reader.readLine().split(" ");
            op = str[0];
            a = Integer.parseInt(str[1]);
            b = Integer.parseInt(str[2]);
            if (op.equals("M")) p[find(a)] = find(b);
            else 
            {
                if (find(a) == find(b)) System.out.println("Yes");
                else System.out.println("No");
            }
        }
    }
}


相关文章
部署hexo后样式丢失问题
部署hexo后样式丢失问题
251 0
|
Java 测试技术 数据处理
Java多线程父线程向子线程传值解决方案 2
Java多线程父线程向子线程传值解决方案
353 0
|
5月前
|
机器学习/深度学习 人工智能 运维
“网太乱,AI来管”——聊聊AI在网络拓扑优化上的骚操作
“网太乱,AI来管”——聊聊AI在网络拓扑优化上的骚操作
437 15
|
5月前
|
人工智能 数据可视化 搜索推荐
什么是低代码开发?3步让你看懂“低代码开发”与“传统开发”的区别
低代码开发自2014年由Forrester提出后逐渐升温,尤其近两年因高效、易用等特点成为热门领域。本文解析低代码与传统开发的区别,前者通过可视化界面和拖放组件简化开发流程,适用于业务管理层应用;后者以手写代码为主,灵活性高但成本大。低代码的核心价值包括自动数据收集、规范业务流程、促进数据共享、减少开发人员需求、个性化搭建、降低成本及提升市场响应速度等,助力企业数字化转型。未来,结合AI技术的低代码将成企业转型的重要基础设施。
|
Java 编译器
Java一分钟之——异常分类:检查异常与运行时异常
【5月更文挑战第20天】Java异常处理分为检查异常(Checked Exceptions)和运行时异常(Unchecked Exceptions),两者在编译期处理方式不同。检查异常需捕获或声明,如`IOException`,而运行时异常如`NullPointerException`在运行时终止程序。常见问题包括不恰当的异常使用、过度捕获和忽略异常信息。避免策略包括正确区分异常类型、具体捕获和处理异常信息。示例代码展示了如何处理这两种类型的异常。理解并妥善处理异常能提升程序的健壮性和可维护性。
323 4
|
运维 监控 Python
自动化运维:使用Python脚本实现日常任务
【9月更文挑战第24天】在现代的软件开发周期中,运维工作扮演着至关重要的角色。本文将介绍如何利用Python编写简单的自动化脚本,来优化和简化日常的运维任务。从备份数据到系统监控,Python的易用性和强大的库支持使其成为自动化运维的首选工具。跟随这篇文章,你将学习如何使用Python编写自己的自动化脚本,提高运维效率,减少人为错误,并最终提升整个开发流程的质量。
|
传感器 自动驾驶 安全
计算机视觉在自动驾驶中的应用:技术解析与未来展望
【8月更文挑战第4天】自动驾驶依托计算机视觉实现环境感知与决策,通过目标检测、跟踪及车道识别等技术保障行车安全与效率。面对数据处理、场景理解等挑战,未来技术将持续优化,深化智能驾驶体验,引领交通行业变革。
|
开发框架 前端开发 JavaScript
基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面
基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面
|
监控 安全 网络安全
|
JSON 分布式计算 大数据
MaxCompute产品使用合集之大数据计算MaxCompute 要提取JSON字符串中的所有key-value对,我该怎么操作
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。