代码随想录Day69(图论Part05)

并查集

java 复制代码
// 1.初始化
int fa[MAXN];
void init(int n)
{
    for (int i=1;i<=n;++i)
        fa[i]=i;
}

// 2.查询
找到的祖先直接返回,未进行路径压缩
int.find(int i){
   if(fa[i] == i)
     return i;// 递归出口,当到达了祖先位置,就返回祖先
   else
    return find(fa[i]);// 不断往上查找祖先
}


// 3.合并
void unionn(int i,int j)
    int i_fa=find(i);// 找到i的祖先    
    int j_fa=find(j);// 找到j的祖先
    fa[i_fa]=j_fa;// i的祖先指向j的祖先。
}

路径压缩,也就是在某一次find函数执行过程中,更新子节点的指向,直接指向顶级节点

107.寻找存在的路径

题目:107. 寻找存在的路径 (kamacoder.com)

思路:难道说,使用并查集的find函数,遍历所有的边,将节点的父亲信息存起来,如果source和destination没有指向同一个根节点,那么就说明不存在路径

尝试(不对)
java 复制代码
import java.util.*;

class Main{
    public static int n;
    public static int m;
    public static int[] fa;
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        m = scanner.nextInt();
        fa = new int[n];
        
        for(int i = 0; i<n; i++){
            fa[i] = i;
        }
        
        for(int i = 0; i<m; i++){
            int n1 = scanner.nextInt();
            int n2 = scanner.nextInt();
            union(n1,n2);
        }
        int source = scanner.nextInt();
        int destination = scanner.nextInt();
        if(source == find(destination)){
            System.out.println(1);
        }else{
            System.out.println(0);
        }
    }
    public static void union(int i , int j){
        int i_fa = find(i);
        int j_fa = find(j);
        fa[i_fa] = j_fa;
    }
    public static int find(int j){
        if(j==fa[j])
            return j;
        else{
            fa[j] = find(fa[j]);
            return fa[j];
        }
    }
}
答案
java 复制代码
import java.util.Scanner;

public class Main {
    private static int[] father;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt(); // 节点数量
        int m = scanner.nextInt(); // 边的数量

        // 初始化并查集
        father = new int[n + 1];
        init(n);

        // 读取边并构建并查集
        for (int i = 0; i < m; i++) {
            int s = scanner.nextInt();
            int t = scanner.nextInt();
            join(s, t);
        }

        int source = scanner.nextInt(); // 起始节点
        int destination = scanner.nextInt(); // 目标节点

        // 判断是否在同一个集合中
        if (isSame(source, destination)) {
            System.out.println(1);
        } else {
            System.out.println(0);
        }
    }

    // 并查集初始化
    private static void init(int n) {
        for (int i = 1; i <= n; i++) {
            father[i] = i;
        }
    }

    // 并查集里寻根的过程
    private static int find(int u) {
        if (u != father[u]) {
            father[u] = find(father[u]);
        }
        return father[u];
    }

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

    // 将 v -> u 这条边加入并查集
    private static void join(int u, int v) {
        int rootU = find(u);
        int rootV = find(v);
        if (rootU != rootV) {
            father[rootV] = rootU;
        }
    }
}
小结
相关推荐
fie88896 小时前
NSCT(非下采样轮廓波变换)的分解和重建程序
算法
晨晖26 小时前
单链表逆转,c语言
c语言·数据结构·算法
im_AMBER8 小时前
Leetcode 78 识别数组中的最大异常值 | 镜像对之间最小绝对距离
笔记·学习·算法·leetcode
鼾声鼾语8 小时前
matlab的ros2发布的消息,局域网内其他设备收不到情况吗?但是matlab可以订阅其他局域网的ros2发布的消息(问题总结)
开发语言·人工智能·深度学习·算法·matlab·isaaclab
LYFlied8 小时前
【每日算法】LeetCode 25. K 个一组翻转链表
算法·leetcode·链表
Swizard9 小时前
别再迷信“准确率”了!一文读懂 AI 图像分割的黄金标尺 —— Dice 系数
python·算法·训练
s09071369 小时前
紧凑型3D成像声纳实现路径
算法·3d·声呐·前视多波束
可爱的小小小狼9 小时前
算法:二叉树遍历
算法
d111111111d10 小时前
在STM32函数指针是什么,怎么使用还有典型应用场景。
笔记·stm32·单片机·嵌入式硬件·学习·算法
AI科技星10 小时前
质量定义方程常数k = 4π m_p的来源、推导与意义
服务器·数据结构·人工智能·科技·算法·机器学习·生活