图论:并查集的合并、判断和求节点

news/2024/7/15 17:18:41 标签: 图论, 算法, c++, 数据结构

 所谓并查集就是可以画图理解

假如说我们想要构建一个树(也是图),要求1->2,2->4,1->3

在构另一个树,要求5->6,6->7,5->8

1是2的头结点,2是4的头结点,以此类推

下面要求去将5连接到1上,就是我下面要讲的,其实上面的子节点的连接也是如此的。

简单并查集例题:

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

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

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

第一行输入整数 n 和 m。

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

输出格式

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

每个结果占一行。

分析一下:

面对这种比较新的数据结构一般都是非常抽象的,但是一旦通过画图或者推理理解了,也就很容易记住了,首先我们将p[i]=i,为的是存储此树的头结点,接下来要进行连接的操作,就要通过find(),压缩一下路径。将子节点连接到p[b]=find(p[a])(a为子节点,b为父节点),下面都是这种操作。

然后这个题目他让判断是不是在一个集合就可以find(a)==find(b)来判断是不是头结点一样,因为最终find(a)返回的是头结点的值。

代码实现:
 #include<bits/stdc++.h>
 using namespace std;
 const int N=1e5+10;
 int p[N];
 int find(int x){//返回x的祖宗节点+路径压缩
    if(p[x]!=x)p[x]=find(p[x]);//只有祖宗节点才有p[x]=x
    return p[x];
 }
 int n,m;
 signed main(){
     scanf("%d%d",&n,&m);
      for(int i=1;i<=n;i++)p[i]=i;
      for(int i=1;i<=m;i++){
         char op[2];//读字符串比读字符更省事
         int a,b;
         scanf("%s%d%d",op,&a,&b);
         if(*op=='M')p[find(a)]=find(b);
         else {
             if(find(a)==find(b))printf("Yes\n");
             else printf("No\n");
         }
      }
 }

下面还有一类题目:让求一个树里面有多少子节点

给定一个包含 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 b 或 Q2 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
分析过程:

 这个题的求节点数,只用拿个数组将所有的子节点连接过程一一地加到父节点的si[b](b为父节点),最后输出的是si[find(a)](a为树中任意一个数)。这样我们就求到了树的节点数。

但是别忘记初始化为si[i]=1,不是si[i]=i

代码实现:
#include<bits/stdc++.h>
#define read(x) scanf("%d",&x)
using namespace std;
const int N = 1e5+5;
int n,m,a,b,fa[N], si[N];
string act;

void init() {//初始化
    for (int i=1; i<=n; i++) {
        fa[i] = i;
        si[i] = 1;
    }
}

int find(int x) {//查找父节点
    if(fa[x]==x) return x;
    else return fa[x] = find(fa[x]);
}

void merge(int a,int b) {//节点数加起来
    int x = find(a);
    int y = find(b);
    fa[x] = y;
    si[y] += si[x];
}

bool ask(int a,int b) {//询问是不是头结点一样
    return find(a)==find(b);
}

int main() {
    read(n),read(m);
    init();
    while(m--) {
        cin>>act;
        if(act=="C") {
            read(a),read(b);
            if(!ask(a,b)) merge(a,b);
        } else if(act=="Q1") {
            read(a),read(b);
            ask(a,b) ? printf("Yes\n") : printf("No\n");
        } else {
            read(a);
            printf("%d\n",si[find(a)]);
        }
    }   
    return 0;
}

以上就是并查集这一种数据结构的代码思路和方法了。


http://www.niftyadmin.cn/n/5332310.html

相关文章

综述:自动驾驶中的 4D 毫米波雷达

论文链接&#xff1a;《4D Millimeter-Wave Radar in Autonomous Driving: A Survey》 摘要 4D 毫米波 (mmWave) 雷达能够测量目标的距离、方位角、仰角和速度&#xff0c;引起了自动驾驶领域的极大兴趣。这归因于其在极端环境下的稳健性以及出色的速度和高度测量能力。 然而…

HarmonyOS—构建第一个ArkTS应用(Stage模型)

创建ArkTS工程 构建第一个页面 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择Application应用开发&#xff0c;选择模板“Empty Ability”&am…

软件测试|使用Python轻松裁剪视频

简介 裁剪视频是在视频编辑和处理中常见的任务之一&#xff0c;Python提供了多种库和工具&#xff0c;可以用来裁剪视频。在本文中&#xff0c;我们将详细讨论如何使用Python来裁剪视频&#xff0c;并提供示例代码。 步骤1&#xff1a;环境准备 首先&#xff0c;我们要安装必…

2、机器学习基础数据探索

加载并理解您的数据。 本课程所需数据集夸克网盘下载链接:https://pan.quark.cn/s/9b4e9a1246b2 提取码:uDzP 文章目录 1、使用Pandas了解你的数据2、解释数据描述1、使用Pandas了解你的数据 任何机器学习项目的第一步都是熟悉数据。您将使用Pandas库进行此操作。Pandas是数…

虚拟化技术、Docker、K8s笔记总结

一、虚拟化技术 是一种将物理资源&#xff08;如服务器、存储设备、网络设备等&#xff09;抽象、转换和分割成多个逻辑资源的技术。通过虚拟化技术&#xff0c;用户可以在单个物理设备上运行多个相互独立的虚拟环境&#xff0c;从而提高资源的利用率、降低运维成本和提高系统…

新版K8s:v1.28拉取Harbor仓库镜像以及本地镜像(docker弃用改用containerd,纯纯踩坑)

目录 一、项目概述二、环境三、项目样式Harborkuboard运行样式 四、核心点Harbor安装config.toml文件修改(containerd)ctr、nerdctl相关命令kuboard工作负载 五、总结 一、项目概述 使用Kuboard作为k8s集群的管理平台&#xff0c;Harbor作为镜像仓库&#xff0c;拉取Harbor镜像…

Redis面试大全

1、什么是Redis? Redis是完全开源免费的&#xff0c;遵守BSD协议&#xff0c;是一个高性能的key-value数据库。 Redis与其他key-value缓存产品有以下三个特点&#xff1a; Redis支持数据的持久化&#xff0c;可以将内存中的数据保存在磁盘中&#xff0c;重启的时候可以再次…

PPT自动化处理

python-pptx模块 可以创建、修改PPT(.pptx)文件非Python标准模块&#xff0c;需要单独安装 在线安装方式 pip install python-pptx 读取slide幻灯片 .slides 获取shape形状 slide.shapes 判断一个shape中是否存在文字 shape.has_text_frame 获取文字框 shape.text_f…