代码随想录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;
        }
    }
}
小结
相关推荐
明月看潮生25 分钟前
青少年编程与数学 02-019 Rust 编程基础 09课题、流程控制
开发语言·算法·青少年编程·rust·编程与数学
oioihoii32 分钟前
C++23 views::slide (P2442R1) 深入解析
linux·算法·c++23
yuhao__z1 小时前
代码随想录算法训练营第六十三天| 图论9—卡码网47. 参加科学大会,94. 城市间货物运输 I
算法·图论
June`1 小时前
专题三:穷举vs暴搜vs深搜vs回溯vs剪枝(全排列)决策树与递归实现详解
c++·算法·深度优先·剪枝
vlln2 小时前
适应性神经树:当深度学习遇上决策树的“生长法则”
人工智能·深度学习·算法·决策树·机器学习
冲帕Chompa2 小时前
图论part09dijkstra算法
算法·图论
·云扬·3 小时前
【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现
redis·算法·lua
周Echo周3 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
zkmall3 小时前
推荐算法工程化:ZKmall模板商城的B2C 商城的用户分层推荐策略
算法·机器学习·推荐算法
矿渣渣3 小时前
AFFS2 的 `yaffs_ext_tags` 数据结构详解
数据结构·算法·文件系统·yaffs2