代码随想录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;
        }
    }
}
小结
相关推荐
倒头就睡的小比特4 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼4 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark4 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her14 天前
并查集-听课笔记
笔记·算法·并查集
码流子4 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven4 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark4 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218614 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法