✏️记笔记:
并查集属于高级算法的一种,但是根据历年省赛真题来看,只要掌握了该模板,那几乎就是送分题哦,我将从这三道经典的并查集题目来带大家学习并查集模板!!
🎠1、合根植物
package Day_Day_work;
import java.util.Scanner;
/**
* @author yx
* @date 2022-03-25 20:18
*/
public class 合根植物___并查集 {
static int[] father=new int[1000010];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m=scanner.nextInt();
int n=scanner.nextInt();
int k=scanner.nextInt();
for (int i = 1; i <=m*n ; i++) {//初始化父节点
father[i]=i;
}
for (int i = 0; i < k; i++) {
int a=scanner.nextInt();
int b=scanner.nextInt();
if(Findfather(a)!=Findfather(b)){
union(a,b);
}
}
int ans=0;
for (int i = 1; i <=m*n ; i++) {
if(father[i]==i){
ans++;
}
}
System.out.println(ans);
}
private static int Findfather(int a) {//寻找祖宗节点
if(a==father[a]){
return a;
}
/**
* 路径压缩
*/
// return Findfather(father[a]);
father[a]=Findfather(father[a]);//父节点设置为根节点
return father[a];
}
private static void union(int a, int b) {//合并
a=Findfather(father[a]);
b=Findfather(father[b]);
// if(Findfather(a)!=Findfather(b)){
// father[Findfather(a)]=b;
// }
if(a!=b){
father[a]=b;
}
}
}
🎏2、亲戚
package Day_Day_work;
import java.util.Scanner;
/**
* @author yx
* @date 2022-04-04 19:06
*/
public class 亲戚__并查集 {
static int fa[]=new int[5010];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt();
int m=scanner.nextInt();
int q=scanner.nextInt();
for (int i = 1; i <=n ; i++) {//初始化亲戚
fa[i]=i;
}
for (int i = 1; i <=m ; i++) {
int a=scanner.nextInt();
int b=scanner.nextInt();
gx(a,b);
}
for (int i = 1; i <=q ; i++) {
int a=scanner.nextInt();
int b=scanner.nextInt();
if(find(a)==find(b)){
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
}
static void gx(int x,int y){//合并操作
fa[find(x)]=find(y);
return;
}
static int find(int x){//找祖先
if(fa[x]==x){
return x;
}
fa[x]=find(fa[x]);
return fa[x];
}
}
🧵3、七段码
package Day_Day_work.problem;
/**
* @author yx
* @date 2022-04-03 23:12
*/
public class 七段码__dfs__并查集 {
static int e[][]=new int[8][8];//存储灯管的连通情况
static int fa[]=new int[8];//并查集的父节点
static boolean isTrue[]=new boolean[8];
static int ans=0;
public static void main(String[] args) {
//连边建图
//a b c d e f g
//1 2 3 4 5 6 7
//e[i][j]=1表示i灯光和j灯光是相互连接的
e[1][2]=e[1][6]=1;
e[2][1]=e[2][7]=e[2][3]=1;
e[3][2]=e[3][4]=e[3][7]=1;
e[4][3]=e[4][5]=1;
e[5][4]=e[5][6]=e[5][7]=1;
e[6][1]=e[6][5]=e[6][7]=1;
dfs(1);
System.out.println(ans);
}
static void dfs(int n){
if(n==8){//出口,遍历了每一盏灯的情况
for (int i = 1; i <=7 ; i++) {//初始化每一个父节点
fa[i]=i;
}
for (int i = 1; i <=7 ; i++) {
for (int j = 1; j <=7 ; j++) {
if(isTrue[i]&&isTrue[j]&&e[i][j]==1){//如果当前两盏相互连接的灯处于打开的状态则放在一个集合里
fa[find(i)]=find(j);//合并操作
}
}
}
int cnt=0;//用来记录联通情况
for (int i = 1; i <=7 ; i++) {
if(isTrue[i]&&fa[i]==i){
cnt++;
}
}
//当有且仅有一种联通亮灯情况的时候才合法,这个时候ans++
if(cnt==1)ans++;
return;
}
isTrue[n]=true;//当前第n盏灯是打开的
dfs(n+1);//递归
isTrue[n]=false;//当前第n盏灯是关闭的
dfs(n+1);
}
static int find(int x){//寻找父节点
if(x==fa[x]){
return x;
}else {
fa[x]=find(fa[x]);
return fa[x];
}
}
}
🚀写在最后
距离蓝桥杯只有四天啦!!
博主争取再更一篇BFS的押题篇,希望大家多多支持!✨
最后,博主想送给大家一句话:
你逆光而来
配得上所有的美好