ProblemSet of Union Find

2024-04-20 12:58
文章标签 union find problemset

本文主要是介绍ProblemSet of Union Find,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

并查集模板:

快速查找 并查集

这是一个eager的并查集,就是在合并两个节点的时候将这两个节点的组份id修改成同一个根节点的编号.

public class QuickFindUF {private int[] componentID; //各个节点(数组索引)所属的组份(数组值)private int count; // number of componentspublic QuickFindUF(int n){if(n<0) throw new IllegalArgumentException();this.count=n;this.componentID=new int[n];for(int i=0;i<n;i++){componentID[i]=i;}}//连接两个节点    O(n)public void union(int p,int q){int rootP=this.find(p);int rootQ=this.find(q);if(rootP==rootQ)return;int label=Math.min(rootP, rootQ);int max=Math.max(rootP, rootQ);for(int i=0;i<this.componentID.length;i++)if(this.componentID[i]==max)this.componentID[i]=label;count--;}//在查找p节点所属组份ID过程中会将实际上同属于一个组份的不同ID修改成相同public int find(int p){int n=this.componentID.length;if(p<0||p>=n)throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));while(p!=this.componentID[p]){this.componentID[p]=componentID[componentID[p]];p=componentID[p];}return p;}public boolean isConnected(int p,int q){int n=this.componentID.length;if(p<0 || p>=n || q<0 || q>=n)throw new IllegalArgumentException("index " + p +" or "+q+ " is not between 0 and " + (n-1));return this.find(p)==this.find(q);}public int count(){return this.count;}
}

快速合并 并查集

public class QuickUnionUF {private int[] componentID;private int count; // number of componentspublic QuickUnionUF(int n){if(n<0) throw new IllegalArgumentException();this.count=n;this.componentID=new int[n];for(int i=0;i<n;i++){componentID[i]=i;}}//连接两个节点void union(int p,int q)	//O(N){int rootP=this.find(p);int rootQ=this.find(q);if(rootP==rootQ)return;this.componentID[rootP]=rootQ;count--;}//在查找p节点所属组份ID过程中会将实际上同属于一个组份的不同ID修改成相同int find(int p)	//O(N){int n=this.componentID.length;if(p<0||p>=n)throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));while(p!=this.componentID[p]){this.componentID[p]=componentID[componentID[p]];p=componentID[p];}return p;}boolean isConnected(int p,int q)	//O(N){int n=this.componentID.length;if(p<0 || p>=n || q<0 || q>=n)throw new IllegalArgumentException("index " + p +" or "+q+ " is not between 0 and " + (n-1));return this.find(p)==this.find(q);}int count(){return this.count;}

加权快速合并 并查集

public class WeightedQuickUnionUF {/** 加权快速合并并查集在快速合并并查集基础上:把 深度较小的树合并到较大的树上*/int[] componentID;int[] size; //以下标i为根节点的节点数int count; // number of componentspublic WeightedQuickUnionUF(int n)  //O(N){if(n<0) throw new IllegalArgumentException();this.count=n;this.componentID=new int[n];this.size=new int[n]; //以索引i为根节点的树的总结点数for(int i=0;i<n;i++){componentID[i]=i;this.size[i]=1;}}//连接两个节点void union(int p,int q)	//O(1){int rootP=this.find(p);int rootQ=this.find(q);if(rootP==rootQ)return;if(this.size[rootP]<=this.size[rootQ]){this.size[rootQ]+=this.size[rootP];this.componentID[rootP]=rootQ;}else{this.size[rootP]+=this.size[rootQ];this.componentID[rootQ]=rootP;}count--;}//在查找p节点所属组份ID过程中会将实际上同属于一个组份的不同ID修改成相同int find(int p)  //O(N),O(the depth of p) if given root nodes{int n=this.componentID.length;if(p<0||p>=n)throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));while(p!=this.componentID[p]){this.componentID[p]=componentID[componentID[p]];p=componentID[p];}return p;}boolean isConnected(int p,int q){int n=this.componentID.length;if(p<0 || p>=n || q<0 || q>=n)throw new IllegalArgumentException("index " + p +" or "+q+ " is not between 0 and " + (n-1));return this.find(p)==this.find(q);}int count(){return this.count;}
}

加权路径压缩快速合并 并查集

public class WeightedQuickUnionPathCompressionUF {int[] father;int[] size;int count; // number of componentspublic WeightedQuickUnionPathCompressionUF(int n)  //O(N){if(n<0) throw new IllegalArgumentException();this.count=n;this.father=new int[n];this.size=new int[n]; //以索引i为根节点的树的总结点数for(int i=0;i<n;i++){father[i]=i;this.size[i]=1;}}//连接两个节点boolean union(int p,int q)	//O(1){int rootP=this.find(p);int rootQ=this.find(q);if(rootP==rootQ)return false;if(this.size[rootP]<=this.size[rootQ]){this.size[rootQ]+=this.size[rootP];this.father[rootP]=rootQ;}else{this.size[rootP]+=this.size[rootQ];this.father[rootQ]=rootP;}count--;return true;}//在查找p节点所属组份ID过程中会将实际上同属于一个组份的不同ID修改成相同int find(int p)  //O(N),O(the depth of p) if given root nodes{int n=this.father.length;if(p<0||p>=n)throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));int root=p;while(root!=this.father[root])root=this.father[root];while(p!=root){int new_root=this.father[p];this.father[p]=root;p=new_root;}return p;}boolean isConnected(int p,int q){int n=this.father.length;if(p<0 || p>=n || q<0 || q>=n)throw new IllegalArgumentException("index " + p +" or "+q+ " is not between 0 and " + (n-1));return this.find(p)==this.find(q);}int count(){return this.count;}

684. Redundant Connection

class Solution {public static int maxCount=1010;public int[] findRedundantConnection(int[][] edges) {WeightedQuickUnionPathCompressionUF uf=new WeightedQuickUnionPathCompressionUF(maxCount);for(int[] e:edges){if(!uf.union(e[0],e[1]))return e;}return new int[]{0,0};}
}public class WeightedQuickUnionPathCompressionUF {int[] father;int[] size;int count; // number of componentspublic WeightedQuickUnionPathCompressionUF(int n)  //O(N){if(n<0) throw new IllegalArgumentException();this.count=n;this.father=new int[n];this.size=new int[n]; //以索引i为根节点的树的总结点数for(int i=0;i<n;i++){father[i]=i;this.size[i]=1;}}//连接两个节点boolean union(int p,int q)	//O(1){int rootP=this.find(p);int rootQ=this.find(q);if(rootP==rootQ)return false;if(this.size[rootP]<=this.size[rootQ]){this.size[rootQ]+=this.size[rootP];this.father[rootP]=rootQ;}else{this.size[rootP]+=this.size[rootQ];this.father[rootQ]=rootP;}count--;return true;}//在查找p节点所属组份ID过程中会将实际上同属于一个组份的不同ID修改成相同int find(int p)  //O(N),O(the depth of p) if given root nodes{int n=this.father.length;if(p<0||p>=n)throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));int root=p;while(root!=this.father[root])root=this.father[root];while(p!=root){int new_root=this.father[p];this.father[p]=root;p=new_root;}return p;}boolean isConnected(int p,int q){int n=this.father.length;if(p<0 || p>=n || q<0 || q>=n)throw new IllegalArgumentException("index " + p +" or "+q+ " is not between 0 and " + (n-1));return this.find(p)==this.find(q);}int count(){return this.count;}
}

[外交]
在这里插入图片描述

package ShunFeng;import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;public class Main1 {public static void main(String[] args) {Scanner cin = new Scanner(System.in);int n = cin.nextInt();    // 参会人数int m = cin.nextInt();    // 语言数量int k = cin.nextInt();    // 记录条数HashMap<Integer, ArrayList<Integer>> record = new HashMap<>();for (int i = 0; i < k; i++) {int a = cin.nextInt(), b = cin.nextInt();if (record.containsKey(b)) {record.get(b).add(a);} else {ArrayList<Integer> tmp = new ArrayList<>();tmp.add(a);record.put(b, tmp);}}QuickUnionUF uf = new QuickUnionUF(n);  //建立大小为n的并查集,不会任何语言的人或者只会一种语言(并且该语言不被其他任何人掌握的)始终独立为一个组份for (int i : record.keySet()) {ArrayList<Integer> arr = record.get(i);int a = arr.get(0);for (int j = 1; j < arr.size(); j++) {uf.union(a-1, arr.get(j)-1);  //人的编号减一对应数组下标的范围}}System.out.println(uf.count()-1);/*7 4 91 12 13 14 23 24 35 36 33 41->(1,2,3)2->(4,3)3->(4,5,6)4->(3)3 3 22 33 1*/}
}public class QuickUnionUF {private int[] componentID;private int count; // number of componentspublic QuickUnionUF(int n){if(n<0) throw new IllegalArgumentException();this.count=n;this.componentID=new int[n];for(int i=0;i<n;i++){componentID[i]=i;}}//连接两个节点void union(int p,int q)	//O(N){int rootP=this.find(p);int rootQ=this.find(q);if(rootP==rootQ)return;this.componentID[rootP]=rootQ;count--;}//在查找p节点所属组份ID过程中会将实际上同属于一个组份的不同ID修改成相同int find(int p)	//O(N){int n=this.componentID.length;if(p<0||p>=n)throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));while(p!=this.componentID[p]){this.componentID[p]=componentID[componentID[p]];p=componentID[p];}return p;}boolean isConnected(int p,int q)	//O(N){int n=this.componentID.length;if(p<0 || p>=n || q<0 || q>=n)throw new IllegalArgumentException("index " + p +" or "+q+ " is not between 0 and " + (n-1));return this.find(p)==this.find(q);}int count()  //返回组份数{return this.count;}
}

这篇关于ProblemSet of Union Find的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920323

相关文章

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

C和指针:结构体(struct)和联合(union)

结构体和联合 结构体 结构体包含一些数据成员,每个成员可能具有不同的类型。 数组的元素长度相同,可以通过下标访问(转换为指针)。但是结构体的成员可能长度不同,所以不能用下标来访问它们。成员有自己的名字,可以通过名字访问成员。 结构声明 在声明结构时,必须列出它包含的所有成员。 struct tag {member-list} variable-list ; 定义一个结构体变量x(包含

MongoDB学习—(6)MongoDB的find查询比较符

首先,先通过以下函数向BookList集合中插入10000条数据 function insertN(obj,n){var i=0;while(i<n){obj.insert({id:i,name:"bookNumber"+i,publishTime:i+2000})i++;}}var BookList=db.getCollection("BookList")调用函数,这样,BookList

【NodeJS】Error: Cannot find module 'ms'

转载自:http://blog.csdn.net/echo_ae/article/details/75097004 问题: Error: Cannot find module 'ms'at Function.Module._resolveFilename (module.js:469:15)at Function.Module._load (module.js:417:25)at Module

leetCode#448. Find All Numbers Disappeared in an Array

Description Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this

访问controller404:The origin server did not find a current representation for the target resource

ider build->rebuild project。Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。由于 Rebuild 的目标只有 Project,所以 Rebuild 每次花的时间会比较长。 参考:资料

mybatis错误——java.io.IOException Could not find resource comxxxxxxMapper.xml

在学习Mybatis的时候,参考网上的教程进行简单demo的搭建,配置的没有问题,然后出现了下面的错误! Exception in thread "main" java.lang.RuntimeException: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: