并查集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"); } } } } }

浙公网安备 33010602011771号