day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)

并查集理论基础

基础内容

并查集常用来解决连通性问题,主要有两个功能:

  • 将两个元素添加到一个集合中
  • 判断两个元素在不在同一个集合

将三个元素A,B,C (分别是数字)放在同一个集合,其实就是将三个元素连通在一起,只需要用一个一维数组来表示,即:father[A] = B,father[B] = C (有向连通图)。对ABC进行寻根,如果都是C,说明在同一个集合里。 此时需要初始化father[C] = C

路径压缩

由于搜索过程像是一个多叉树中从叶子到根节点的过程,如果多叉树高度很深的话,每次find函数寻找根的过程就要递归很多次。所以将除了根节点其他所有节点都挂载根节点下,在寻根的时候就很快。

路径压缩的核心思想是在查找某个节点的根节点时,将沿途的所有节点直接连接到根节点。

并查集模版C++

c 复制代码
int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构

// 并查集初始化
void init() {
    for (int i = 0; i < n; ++i) {
        father[i] = i;
    }
}
// 并查集里寻根的过程
int find(int u) {
    return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
}

// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {
    u = find(u);
    v = find(v);
    return u == v;
}

// 将v->u 这条边加入并查集
void join(int u, int v) {
    u = find(u); // 寻找u的根
    v = find(v); // 寻找v的根
    if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
    father[v] = u;
}

并查集主要有三个功能:

  • 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
  • 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
  • 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点

寻找存在的路径

对模版的直接应用,学习一下如何使用Java表示模版

java 复制代码
import java.util.*;
public class Main{
    public static void main (String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt();
        int m=scan.nextInt();
        DisJoint disJoint=new DisJoint(n+1);
        for(int i=0;i<m;i++){
            disJoint.join(scan.nextInt(),scan.nextInt());
        }
        if(disJoint.isSame(scan.nextInt(),scan.nextInt())) System.out.println("1");
        else System.out.println("0");
    }
}

class DisJoint{
    private int[] father;
    public DisJoint(int N){
        father=new int[N];
        for(int i=0;i<N;i++){
            father[i]=i;
        }
    }
    
    public int find(int n){
        return n==father[n]?n:(father[n]=find(father[n]));
    }
    
    public void join(int u,int v){
        u=find(u);
        v=find(v);
        if(u==v) return;
        father[v]=u;
    }
    
    public boolean isSame(int u,int v){
        u=find(u);
        v=find(v);
        return u==v;
    }
}
相关推荐
Coovally AI模型快速验证25 分钟前
农田扫描提速37%!基于检测置信度的无人机“智能抽查”路径规划,Coovally一键加速模型落地
深度学习·算法·yolo·计算机视觉·transformer·无人机
pusue_the_sun28 分钟前
数据结构:二叉树oj练习
c语言·数据结构·算法·二叉树
一叶飘零_sweeeet1 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
RaymondZhao341 小时前
【全面推导】策略梯度算法:公式、偏差方差与进化
人工智能·深度学习·算法·机器学习·chatgpt
艾伦~耶格尔1 小时前
【集合框架LinkedList底层添加元素机制】
java·开发语言·学习·面试
zhangfeng11331 小时前
DBSCAN算法详解和参数优化,基于密度的空间聚类算法,特别擅长处理不规则形状的聚类和噪声数据
算法·机器学习·聚类
一只叫煤球的猫2 小时前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
最初的↘那颗心2 小时前
Flink Stream API 源码走读 - print()
java·大数据·hadoop·flink·实时计算
啊阿狸不会拉杆2 小时前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路2 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法