day52 代码随想录算法训练营 图论专题5

1 今日打卡

并查集基础理论 并查集理论基础 | 代码随想录

寻找存在的路线 107. 寻找存在的路线

2 并查集基础理论

当我们需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集。

模板:

3 寻找存在的路径

3.1 思路

初始化并查集:为每个节点建立独立的集合(父节点指向自己);

合并连通节点:遍历所有边,将每条边的两个节点合并到同一个集合中;

判断连通性:检查目标两个节点是否属于同一个集合(根节点相同),输出结果。

3.2 实现代码

java 复制代码
import java.util.*;

public class Main {
    // 定义并查集内部类,用于管理节点的连通关系
    static class disJoint {
        // 父节点数组:father[i]表示节点i的父节点(静态仅因本题单实例,实际建议去掉static)
        public static int[] father;

        // 并查集构造方法:初始化n个节点的父节点
        public disJoint(int n) {
            // 节点编号从1开始(题目常见输入习惯),数组长度设为n+1
            father = new int[n + 1];
            // 初始化:每个节点的父节点是自己(独立集合)
            for (int i = 0; i <= n; i++) {
                father[i] = i;
            }
        }

        // 查找节点u的根节点(带路径压缩,优化查找效率)
        public int find(int u) {
            // 递归终止条件:u是自己的父节点(u是根节点)
            if (u == father[u]) {
                return u;
            }
            // 路径压缩:将u的父节点直接指向根节点(扁平化树结构)
            father[u] = find(father[u]);
            // 返回压缩后的根节点
            return father[u];
        }

        // 合并两个节点u和v所在的集合
        public void join(int u, int v) {
            // 先找到u的根节点
            u = find(u);
            // 先找到v的根节点
            v = find(v);
            // 如果根节点相同,说明已在同一集合,无需合并
            if (u == v) {
                return;
            }
            // 合并:将v的根节点指向u的根节点(统一集合)
            father[v] = u;
        }

        // 判断两个节点是否在同一个集合(是否连通)
        public boolean isSame(int u, int v) {
            // 找到u的根节点
            u = find(u);
            // 找到v的根节点
            v = find(v);
            // 根节点相同则连通,否则不连通
            return u == v;
        }
    }

    // 主方法:程序入口,处理输入、调用并查集、输出结果
    public static void main(String[] args) {
        // 创建Scanner对象,读取控制台输入
        Scanner sc = new Scanner(System.in);
        // 读取第一个整数n(节点总数),第二个整数m(边的总数)
        int n = sc.nextInt(), m = sc.nextInt();
        // 初始化并查集,容量为n
        disJoint dj = new disJoint(n);

        // 遍历m条边,合并每条边的两个节点
        for (int i = 0; i < m; i++) {
            // 读取当前边的两个节点a和b
            int a = sc.nextInt(), b = sc.nextInt();
            // 合并节点a和b到同一集合
            dj.join(a, b);
        }

        // 读取需要判断连通性的两个节点from和to
        int from = sc.nextInt(), to = sc.nextInt();
        // 判断两个节点是否连通
        if (dj.isSame(from, to)) {
            // 连通则输出1
            System.out.println(1);
        } else {
            // 不连通则输出0
            System.out.println(0);
        }
        // 关闭Scanner,释放资源
        sc.close();
    }
}
相关推荐
zh_xuan7 分钟前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
机 _ 长16 分钟前
05 智算运维|8 张卡怎么才算「捆成一张」:NCCL 实测与拓扑
运维·人工智能·算法·智算运维
早起CaiCai1 小时前
【2023-01 OM】利用深度学习算法融合异质观测实现海洋场降尺度
人工智能·深度学习·算法
学长毕设1 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
梦里寻码2 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
SL_staff2 小时前
离散制造排程破局:JVS-APS 四步闭环落地实践(开发者视角)
java·产品·全栈
这个昵称不容易2 小时前
SpringBoot 美容院管理系统:232个Java文件315个接口,5套角色从预约到发货一整条链路
java·springboot·毕设
猿人谷2 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
装不满的克莱因瓶3 小时前
【SpringAI Alibaba】ReactAgent记忆管理MessageTrimmingHook与MessageDeletionHook
java·人工智能·ai·ai编程·springai·springaialibaba
文丑颜不良啊3 小时前
LeetCode2241~2260题目解析
java·leetcode