蓝桥杯冲刺——并查集

并查集思想

关于并查集的思想,如果不了解的话可以参考一下这篇文章:链接: 【算法与数据结构】—— 并查集.

简单来说,我们想如果要知道数据间是否是连通的,或者是否具有某种关系,就可以通过find()函数来查找它们是否拥有公共的上级,同时,我们还可以通过join()函数来添加上级。

find()函数

find()函数的功能是为了找到它的最上级。这里我们直接使用优化的并查集,我们先定义一个数组pre[],pre[i]存放的就是i的最上级。具体实现代码:

public static int find(int x) {
		if(pre[x] == x) return x;
		return pre[x] = find(pre[x]);
	}

join()函数

join()函数是起到合并的功能,也就是将它们的最上级指定为同一个(选取哪一个上级随意)
实现代码:

public static void join(int x,int y) {
		int fx = find(x),fy = find(y);
		if(fx!=fy)
			pre[fx] = fy;
	}

注意这里是最上级之间的层级设置,不是x,y间的,这个地方没注意我改了半天orz

合根植物

链接: 合根植物.
在这里插入图片描述
这里可以看出是很基础的并查集考察了,直接套用模板就好了

完整代码

代码1:
这里的步骤比较清晰,boolean[]相当于辅助数组,方便理解

import java.util.Scanner;
public class test {
    
	public static int[] pre;
	public static boolean[] plants;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int n = sc.nextInt();
		int k =sc.nextInt();
		pre = new int[m*n+1];
		plants = new boolean[m*n+1];
		for(int i=1;i<=m*n;i++) {
			pre[i] =i;
		}
		
		for(int i=0;i<k;i++) {
			int x=sc.nextInt();
			int y=sc.nextInt();
			join(x,y);
		}
		int count=0;
		for(int i=1;i<=m*n;i++) {
			plants[find(i)] = true;
		}
		for(int i=1;i<=m*n;i++) {
			if(plants[i])
				count++;
		}
		System.out.println(count);
	}
	public static int find(int x) {
		if(pre[x] != x) return pre[x] = find(pre[x]);
		
		return x;
	}
	public static void join(int x,int y) {
		int fx=find(x),fy = find(y);
		if(fx!=fy) {
			pre[fy] = fx;
		}
	}

}

代码2:
这里去掉了boolean[]数组,可以少遍历一次

package test;
import java.util.Scanner;
public class test {
    
	public static int[] pre;
	public static int count;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int n = sc.nextInt();
		int k =sc.nextInt();
		count = m*n;
		pre = new int[m*n+1];
		for(int i=1;i<=m*n;i++) {
			pre[i] =i;
		}
		
		for(int i=0;i<k;i++) {
			int x=sc.nextInt();
			int y=sc.nextInt();
			join(x,y);
		}
		System.out.println(count);
	}
	public static int find(int x) {
		if(pre[x] != x) return pre[x] = find(pre[x]);
		
		return x;
	}
	public static void join(int x,int y) {
		int fx=find(x),fy = find(y);
		if(fx!=fy) {
			pre[fy] = fx;
			count--;
		}
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值