代码随想录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;
        }
    }
}
小结
相关推荐
芒克芒克21 小时前
LeetCode 134. 加油站(O(n)时间+O(1)空间最优解)
java·算法·leetcode·职场和发展
TracyCoder1231 天前
LeetCode Hot100(4/100)——283. 移动零
算法·leetcode
啊阿狸不会拉杆1 天前
《计算机操作系统》第七章 - 文件管理
开发语言·c++·算法·计算机组成原理·os·计算机操作系统
黎阳之光1 天前
打破视域孤岛,智追目标全程 —— 公安视频追踪技术革新来袭
人工智能·算法·安全·视频孪生·黎阳之光
jiaguangqingpanda1 天前
Day28-20260124
java·数据结构·算法
TracyCoder1231 天前
LeetCode Hot100(2/100)——49. 字母异位词分组 (Group Anagrams)。
算法·leetcode
lixinnnn.1 天前
字符串拼接:Cities and States S
开发语言·c++·算法
AI街潜水的八角1 天前
医学图像算法之基于MK_UNet的肾小球分割系统3:含训练测试代码、数据集和GUI交互界面
算法
larance1 天前
方差和标准差
人工智能·算法·机器学习
TracyCoder1231 天前
LeetCode Hot100(3/100)——128.最长连续序列
算法·leetcode