并查集java实现

并查集

 

用树来表示每一个集合,根节点编号就是这个集合的编号,每一个点都存储它的父节点p[x]是谁,如何找到元素属于哪个集合?一直找他的父节点,直到根结点,根结点编号就是它的集合

 

 除了根节点之外,x的父节点都不等于x,根节点的父节点就是根结点

 

 

 

 

 

 

如何优化问题2?

一旦找到根结点,将路径上所有点都指向根结点(路径压缩)

 

 

刚开始每个节点都是根节点

 

 

 

 

 

操作1,2跟前面的一样,如何实现操作3?

用一个数组size[N]表示每一个集合中点的数量

初始化,最开始每一个集合中只有一个点,所以size等于1

 

 假设只有根节点的size有意义,当两个集合合并时如何修改size?当a和b不在一个集合中时size[b]+=size[a],b是这两棵树的根节点,只用维护b的size值就可以了,当ab在一个集合中时continue

 

 

import java.util.*;
public class Main{
    static int[] p=new int[100010];
    public static int find(int x){
        if(p[x]!=x){
            p[x]=find(p[x]);
        }
        return p[x];
    }
    public static void main(String[] args){
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt();
        int m=scan.nextInt();
        for(int i=1;i<=n;i++){
            p[i]=i;
        }
        while(m-->0){
            String s=scan.next();
            if(s.equals("M")){
                int a=scan.nextInt();
                int b=scan.nextInt();
                p[find(a)]=find(b);
            }
            else{
                int a=scan.nextInt();
                int b=scan.nextInt();
                if(find(a)==find(b)){
                    System.out.println("Yes");
                }
                else{
                    System.out.println("No");
                }
            }
        }
    }
}

 

posted @ 2022-04-07 22:09  经典的错误  阅读(148)  评论(0)    收藏  举报