连通块中点的数量

简介: 连通块中点的数量

连通块中点的数量

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

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

C a b,在点 a 和点 b 之间连一条边,a 和 b 可能相等;

Q1 a b,询问点 a 和点 b 是否在同一个连通块中,a 和 b 可能相等;

Q2 a,询问点 a 所在连通块中点的数量;

输入格式

第一行输入整数 n 和 m。

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

输出格式

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

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

每个结果占一行。

数据范围

1≤n,m≤105

输入样例:

5 5

C 1 2

Q1 1 2

Q2 1

C 2 5

Q2 5

输出样例:

Yes

2

3

讲解

该题是并查集的应用,乍看像图论,其实是并查集

每一个连通块其实都是一个集合。

  1. 对于连边操作,其实就是集合间的合并。
  2. 对于查询是否在同一连通块,也就是集合的询问操作。
  3. 对于查询连通块中点的数量,也就是查询集合的大小。

因此,我们这题直接用并查集模板就可以完成了。

只是要附加一个s数组记录一下每个集合的大小,在合并的时候加上即可。

提交代码

#include<bits/stdc++.h>
using namespace std;
int n, m;
const int N = 100010;
int p[N], s[N];
int find(int x)
{
    if (x != p[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;
        s[i] = 1;
    }
    while (m --)
    {
        char op[5];
        int a, b;
        scanf ("%s", op);
        if (op[0] == 'C')
        {
            scanf ("%d%d", &a, &b);
            if (find(a) == find(b)) continue;
            s[find(b)] += s[find(a)];
            p[find(a)] = find(b);
        }
        else if (op[1] == '1')
        {
            scanf ("%d%d", &a, &b);
            find(a) == find(b) ? puts("Yes") : puts("No");
        }
        else
        {
            scanf ("%d", &a);
            printf("%d\n", s[find(a)]);
        }
    }
    return 0;
}

下面是一个并查集的题目:

合并集合

一共有 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");
            }
        }
    }
}


相关文章
|
11月前
|
Web App开发 搜索推荐 开发者
浏览器插件上架指南:如何把你的产品搬上浏览器插件市场
在实践了 Chrone、Firefox、Edge、Opera 等 几个主要的插件平台的上架发布工作后,我觉得很有必要把这个过程和思考记录下来,分享给大家,希望能提供一些参考和避坑的经验。我想通过这篇文章,和大家聊聊「为什么我要做这件事」,以及「这个系列文章会包含哪些内容」。我想用一个系列的文章,记录我是如何把 EmojiClick 搬到浏览器插件市场的,也给大家提供一些借鉴经验。
307 19
|
存储 NoSQL Java
Spring Boot与Neo4j图数据库的集成应用
Spring Boot与Neo4j图数据库的集成应用
|
安全 网络协议 网络安全
智能家居技术的安全性分析与防护措施
【7月更文挑战第23天】随着物联网技术的飞速发展,智能家居系统逐渐成为现代生活的一部分。然而,随之而来的安全问题也日益凸显。本文从智能家居系统的架构出发,分析了当前智能家居面临的主要安全威胁,包括物理安全、网络安全和数据隐私保护等方面。进一步探讨了加强智能家居安全性的对策,如采用加密技术、定期更新固件、使用安全的网络协议等。最后,文章强调了用户在智能家居安全防护中的作用,提出了提高用户安全意识的建议。
271 6
|
JSON 监控 测试技术
性能测试--InfluxDB+Grafana+Jmeter搭建性能监控平台 (二)
性能测试--InfluxDB+Grafana+Jmeter搭建性能监控平台
|
存储 缓存 Java
请你详细说说Go的逃逸分析
详细说说Go的逃逸分析
171 0
请你详细说说Go的逃逸分析
|
SQL 存储 自然语言处理
|
物联网 区块链 数据安全/隐私保护
瑞波币创始人:区块链可用于物联网,加密货币只是很小的领域
区块链可用于物联网,加密货币只是很小的领域
1329 0
|
分布式计算 大数据 关系型数据库
阿里云大数据利器之-RDS迁移到Maxcompute实现动态分区
当前,很多用户的业务数据存放在传统关系型数据库上,例如阿里云的RDS,做业务读写操作。当数据量非常大的时候,此时传系关系型数据库会显得有些吃力,那么会经常有将mysql数据库的数据迁移到[大数据处理平台-大数据计算服务(Maxcompute,原ODPS)(https://www.aliyun.com/product/odps?spm=5176.doc27800.765261.309.dcjpg2),利用其强大的存储和计算能力进行各种查询计算,结果再回流到RDS。
9741 0
|
安全 算法 C#
C# 中使用 RSA加解密算法
一、什么是RSA   RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。      在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
2431 0

热门文章

最新文章