Day57:并查集 寻找存在的路径

并查集(Union-Find)是一种数据结构,用于处理一些不交集的合并及查询问题。它主要包含两个操作:

Find

确定某个元素属于哪个子集。通常是通过递归地查找元素的根节点(即其最终的父节点)来实现。

查找元素x所在的集合的根节点。如果x的父节点是x本身,则x就是根节点;否则,递归地查找x的父节点的父节点,直到找到根节点。

Union

将两个子集合并成一个。

将两个元素x和y所在的集合合并。首先找到x和y的根节点,然后将其中一个根节点的父节点指向另一个根节点。

表示方法:

模板:

int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构

// 并查集初始化
void init() {
    for (int i = 0; i < n; ++i) {
        father[i] = i;
    }
}
// 并查集里寻根的过程
int find(int u) {
    return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
}

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

// 将v->u 这条边加入并查集
void join(int u, int v) {
    u = find(u); // 寻找u的根
    v = find(v); // 寻找v的根
    if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
    father[v] = u;
}

通过模板,我们可以知道,并查集主要有三个功能。

  1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
  2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
  3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点

模拟过程:

8->3:路径压缩 

return u == father[u] ? u : father[u] = find(father[u]); 
 


107. 寻找存在的路径

时间限制:1.000S  空间限制:256MB

题目描述

给定一个包含 n 个节点的无向图中,节点编号从 1 到 n (含 1 和 n )。

你的任务是判断是否有一条从节点 source 出发到节点 destination 的路径存在。

输入描述

第一行包含两个正整数 N 和 M,N 代表节点的个数,M 代表边的个数。 

后续 M 行,每行两个正整数 s 和 t,代表从节点 s 与节点 t 之间有一条边。 

最后一行包含两个正整数,代表起始节点 source 和目标节点 destination。

输出描述

输出一个整数,代表是否存在从节点 source 到节点 destination 的路径。如果存在,输出 1;否则,输出 0。

输入示例
5 4
1 2
1 3
2 4
3 4
1 4
输出示例
1
提示信息

数据范围:

1 <= M, N <= 100。

思路:

 


import java.util.*;
public class Main{
    public static void main(String[] args){
        int n,l;
        Scanner in=new Scanner(System.in);
        n=in.nextInt();
        l=in.nextInt();
        M m= new M(n);
        while(l-->0){
            m.join(in.nextInt(),in.nextInt());
        }
        int x=in.nextInt();
        int y=in.nextInt();
        int result=0;
        if( m.isSame(x,y))result=1 ;
        System.out.println(result);
    }

}
class M{
    int[] father;
    public M(int n){
        father=new int[n+1];
        for(int i=1;i<=n;i++){
            father[i]=i;
        }
    }
    int find(int i){
        if(father[i]==i){
            return  i;
        }
        father[i]=find(father[i]);
        return father[i];
    }
    boolean isSame(int i,int j){
        i=find(i);
        j=find(j);
        if(i==j) return true;
        return false;
    }

    void join(int i,int j){
        i=find(i);
        j=find(j);
        if(i==j) return;
        father[j]=i;
    }
}

 

相关推荐

  1. 刷题Day57|107. 寻找存在路径

    2024-07-21 19:18:02       15 阅读
  2. ---力扣547省份数量

    2024-07-21 19:18:02       41 阅读
  3. 集训day3:

    2024-07-21 19:18:02       19 阅读
  4. 547. 省份数量

    2024-07-21 19:18:02       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 19:18:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 19:18:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 19:18:02       45 阅读
  4. Python语言-面向对象

    2024-07-21 19:18:02       55 阅读

热门阅读

  1. Huawei、Cisco 路由中 RIP 协议 summary 的用法

    2024-07-21 19:18:02       18 阅读
  2. 密码学原理精解【9】

    2024-07-21 19:18:02       14 阅读
  3. Spring中的事务详解

    2024-07-21 19:18:02       12 阅读
  4. ARM/Linux嵌入式面经(十八):TP-Link联洲

    2024-07-21 19:18:02       16 阅读
  5. Ksyusha and Chinchilla

    2024-07-21 19:18:02       18 阅读
  6. 速盾:金融行业服务器如何避免DDoS攻击?

    2024-07-21 19:18:02       15 阅读
  7. 简单介绍什么是投影仪及投影仪的工作原理

    2024-07-21 19:18:02       15 阅读
  8. websocket

    websocket

    2024-07-21 19:18:02      14 阅读