并查集题目模板及java代码

Posted 知道什么是码怪吗?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集题目模板及java代码相关的知识,希望对你有一定的参考价值。

并查集主要用途:

①将两个集合合并

②查询两个元素是否在同一个集合当中

基本原理:

每个集合用一棵树来表示,树根的编号就是整个集合的编号,每个节点存放父节点。

例如:定义一个数组father,father[x]就表示x的父节点。 

如何判断是否到达了树根?

if(father[x]==x) // 只有树根的父节点定义为自己的位置

如何求x所处在的集合编号?

while(father[x]!=x) //只要存放的父节点和自身不相等,说明不是父节点
    x=father[x];    //然后x跑到父节点的位置

有两个集合father1,father2如何合并两个集合?

//将father1的根节点的父节点值从本身变为father2的根节点。
father1[root1]=root2; //原本father1的根节点的父节点是本身

合并集合

一共有 n个数,编号是 1∼n,最开始每个数各自在一个集合中。

现在要进行 m 个操作,操作共有两种:

  1. M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
  2. Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 M a b 或 Q a b 中的一种。

输出格式

对于每个询问指令 Q a b,都要输出一个结果,如果 a 和 b 在同一集合内,则输出 Yes,否则输出 No

每个结果占一行。

数据范围

1≤n,m≤100000

输入样例:

4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4

输出样例:

Yes
No
Yes

 模板代码:

import java.util.*;

public class Main {
	static int[] nums = new int[100010];

	public static int Find(int number) {// 查找某个数的根节点
		// 递归写法+路径压缩。优化过后所有子节点的父节点都指向根节点,加快速度
		// if(nums[number]!=number)
		// nums[number]=Find(nums[number]);
        // return nums[number];
		// 普通写法
		while (nums[number] != number)// 不相等就继续找
			number = nums[number];
		return number;

	}

	public static void Merge(int number1, int number2) {
		nums[Find(number1)] = Find(number2);// number1的根节点的父节点指向number2的根节点
	}

	public static void main(String args[]) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int m = input.nextInt();
		for (int i = 1; i <= n; i++)
			nums[i] = i;

		for (int i = 0; i < m; i++) {
			String str = input.next();
			int number1 = input.nextInt();
			int number2 = input.nextInt();
			if (str.equals("M"))
				Merge(number1, number2);
			else if (Find(number1) == Find(number2))
				System.out.println("Yes");
			else
				System.out.println("No");
		}
	}
}

连通块中点的数量

给定一个包含 n 个点(编号为 1∼n)的无向图,初始时图中没有边。

现在要进行 mm 个操作,操作共有三种:

  1. C a b,在点 a 和点 b 之间连一条边,aa 和 bb 可能相等;
  2. Q1 a b,询问点 a 和点 b 是否在同一个连通块中,aa 和 bb 可能相等;
  3. Q2 a,询问点 a 所在连通块中点的数量;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 C a bQ1 a b 或 Q2 a 中的一种。

输出格式

对于每个询问指令 Q1 a b,如果 a 和 b 在同一个连通块中,则输出 Yes,否则输出 No

对于每个询问指令 Q2 a,输出一个整数表示点 a 所在连通块中点的数量

每个结果占一行。

数据范围

1≤n,m≤100000

输入样例:

5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5

输出样例:

Yes
2
3
import java.util.*;

public class Main{
    static int[] nums=new int[100010];
    static int[] count=new int[100010];//记录这个节点所在的集合的节点个数
    
    public static void Connect(int number1,int number2){
        int a=Find(number1);//number1的根节点
        int b=Find(number2);//number2的根节点
        if(a!=b){
            nums[a]=b;//number1的根节点的父节点指向number2的根节点       
            count[b]+=count[a];//更新集合中点的个数
        }
    }
    
    public static int Find(int number){//查找这个数的根节点
        while(nums[number]!=number)
            number=nums[number];
        return number;
    }
    
    public static void main(String args[]){
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        int m=input.nextInt();
        for(int i=1;i<=n;i++){
            nums[i]=i;
            count[i]=1;//初始化
        }
        
        for(int i=0;i<m;i++){
            String str=input.next();
            if(str.equals("C")){
                int number1=input.nextInt();
                int number2=input.nextInt();
                Connect(number1,number2);
            }
            else if(str.equals("Q1")){
                int number1=input.nextInt();
                int number2=input.nextInt();
                if(Find(number1)==Find(number2))
                    System.out.println("Yes");
                else 
                    System.out.println("No");
            }
            else{
                int number=input.nextInt();
                System.out.println(count[Find(number)]);
            }    
        }
    }    
}

以上是关于并查集题目模板及java代码的主要内容,如果未能解决你的问题,请参考以下文章

并查集模板并查集模板 luogu-3367

洛谷 P3367- 并查集(Java模板)

The Suspects——并查集求联通块数量的模板题

带权并查集(含种类并查集)经典模板 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug's life(简单) ③hihoCoder 1515 : 分数调查(示例代码(代

How Many Tables——并查集模板题

树的应用——并查集及实现代码