并查集(两个版本)

 1    import java.util.*;
 2
 3     public class DisjointUnionSets1{
 4     int[] rank, parent,size;
 5     int n;
 6
 7         public DisjointUnionSets1(int n){
 8         rank = new int[n];
 9         parent = new int[n];
10         size = new int[n];
11         this.n = n;
12         makeSet();
13         }
14
15       void makeSet(){
16       for (int i=0; i<n; i++){
17       parent[i] = i;
18       size[i]=1;
19
20       }
21      }
22
23
24
25       public int find(int x){                        // Returns representative of x‘s set//
26         if (parent[x]!=x)
27         parent[x] = find(parent[x]);
28
29         return parent[x];
30       }
31
32
33
34      public void unite(int x, int y){
35         int xRoot = find(x), yRoot = find(y);
36         if (xRoot == yRoot)
37             return;
38
39         if(rank[xRoot] < rank[yRoot]){
40            parent[xRoot] = yRoot;
41            size[yRoot]+=size[xRoot];
42
43            }
44         else if(rank[yRoot] < rank[xRoot]){
45            parent[yRoot] = xRoot;
46            size[xRoot]+=size[yRoot];
47
48            }
49
50         else{
51             parent[yRoot] = xRoot;
52             rank[xRoot] = rank[xRoot] + 1;
53             size[xRoot]+=size[yRoot];
54
55
56         }
57      }
58
59
60     public boolean sameSet(int x,int y){
61     return find(x)==find(y);
62     }
63
64
65
66     public boolean isRoot(int x){
67     return find(x)==x;
68     }
69
70
71      public int getSize(int x){
72      return size[x];
73      }
74
75
76
77     public static void main(String[] args){
78      DisjointUnionSets1 dus=new DisjointUnionSets1(6);
79      dus.unite(0,2);
80      dus.unite(2,4);
81      dus.unite(1,3);
82 System.out.println(dus.sameSet(0,4));
83 System.out.println(dus.sameSet(3,1));
84 System.out.println(dus.sameSet(1,5));
85 System.out.println(dus.sameSet(2,3));
86 System.out.println(dus.sameSet(5,3));
87 System.out.println(dus.sameSet(2,0));
88 for(int i=0;i<6;i++)
89 System.out.println(i+":   is root?  "+dus.isRoot(i)+"     size? "+dus.getSize(i));
90 }
91
92
93 }

下面这个版本适用于预先不知道有多少个元素,使用的是泛型:

  1  public class DisJointUnionSets2<E>{
  2     HashMap<E,Node<E>> map=new HashMap<>();
  3
  4
  5         public DisJointUnionSets2(){
  6         }
  7
  8
  9        public void unite(E e1,E e2){
 10        Node<E> n1;
 11        Node<E> n2;
 12        if(!map.containsKey(e1)&& !map.containsKey(e2)){
 13        n1=new Node<>(e1);
 14         n2=new Node<>(e2);
 15         n2.parent=n1;
 16         n1.rank++;
 17         n1.size+=n2.size;
 18         map.put(e1,n1);
 19         map.put(e2,n2);
 20        }
 21
 22     else if(!map.containsKey(e1)){
 23      n1=new Node<>(e1);
 24      n2=getRoot(e2);
 25       n1.parent=n2;
 26       n2.size+=n1.size;
 27       map.put(e1,n1);
 28       }
 29
 30       else if(!map.containsKey(e2)){
 31       n2=new Node<>(e2);
 32       n1=getRoot(e1);
 33       n2.parent=n1;
 34       n1.size+=n2.size;
 35       map.put(e2,n2);
 36       }
 37
 38     else{
 39       n1=getRoot(e1);
 40       n2=getRoot(e2);
 41        if(n1.rank>n2.rank){
 42        n2.parent=n1;
 43        n1.rank=Math.max(n1.rank, 1+n2.rank);
 44        n1.size+=n2.size;
 45       }
 46       else if(n1.rank<n2.rank){
 47        n1.parent=n2;
 48        n2.rank=Math.max(n2.rank, 1+n1.rank);
 49         n2.size+=n1.size;
 50       }
 51       else if(n1.rank==n2.rank && n1!=n2){
 52       n2.parent=n1;
 53       n1.rank=Math.max(n1.rank, 1+n2.rank);
 54        n1.size+=n2.size;
 55       }
 56
 57     }
 58  }
 59
 60
 61
 62 public Node<E> getRoot( E e){
 63 if(!map.containsKey(e))
 64 return new Node<>(e);
 65
 66 Node<E> n=map.get(e);
 67 while(n.parent!=null){
 68 n=n.parent;
 69 }
 70 return n;
 71 }
 72
 73
 74   public boolean sameSet(E x,E y){
 75     return getRoot(x)==getRoot(y);
 76     }
 77
 78
 79
 80     public boolean isRoot(E e){
 81         if(map.containsKey(e) && map.get(e).parent!=null)
 82             return false;
 83         else
 84             return true;
 85     }
 86
 87
 88     public int getSize(E e){
 89         if(map.containsKey(e))
 90             return map.get(e).size;
 91         else
 92         return 1;
 93     }
 94
 95
 96  class Node<E>{
 97  E element;
 98  Node<E> parent;
 99  int rank;
100  int size=1;
101
102  public Node(E e){
103  element=e;
104 }
105 }
106
107 }

原文地址:https://www.cnblogs.com/black-fish/p/9250183.html

时间: 2024-07-30 00:51:30

并查集(两个版本)的相关文章

「带权并查集」奇偶游戏

奇偶游戏 原题链接:奇偶游戏 题目大意 给你N个区间,每个区间给你它含1的奇偶性,问你哪些询问逻辑上冲突 题目题解 一道带权并查集的题,让我对带权并查集有了更深入的理解,带权并查集可以分为两种(在这道题中) "边带权"并查集 "扩展域"并查集 两种方法都是思维上的不同所造成的,其中第一种解法是最常见的,第二种解法在代码实现上是最简单的,我们先来对第一种进行探究 边带权,很明显,我们要在并查集的边上进行一个储存边权的操作,我们这里用d来表示当前节点到根节点的Xor值,

ACM1558两线段相交判断和并查集

Segment set Problem Description A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set. Input In the first line ther

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本] 1. 开发环境 Jdk 1.7.0_72 Maven 3.2.1 Scala 2.10.6 Spark 1.6.2 Hadoop 2.6.4 IntelliJ IDEA 2016.1.1 2. 创建项目1) 新建Maven项目 2) 在pom文件中导入依赖pom.xml文件内容如下: <?xml version="1.0" encoding="UTF-8"?> &l

可持久化并查集的两种实现

对于像UVA 11987 Almost Union-Find这样的题目,要求把一个元素从一个集合中剥离的情况,我们只需要新建一个节点然后---. 还是看代码吧: inline void move(int x,int y) // 把x从y集合中剥离 { int fx = find(id[x]),fy = find(id[y]); if(fx == fy) return ; cnt[fx] --,sum[fx] -= x; id[x] = ++ tot; // 可持久化 f[id[x]] = fy;

Is It A Tree?------HDOJ杭电1325(两种方法,可以用也可以不用并查集!!!!!!详解)

Problem Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties. There is exactly one node, called the

poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are

POJ1703并查集(区分两个集合)

题意:输入n,m.n个人,m个规定/询问.一共有两个集合,A:询问a,b是否在同一个集合?D:表明a,b不在同一个集合.输出有三种,不在同一集合,在同一集合,不确定. 解析:其实有点离散化的意思.传统并查集是合并两个集合,而这个题是分开两个集合.那么可以这么做,想办法进行合并操作.输入a,b,a,b没有了关系,但是可以规定,a+n,b属同一集合,a,b+n属于同一集合.即,n右边a+n的那些和b放入同一集合,n右边b+n的那些和a放入同一集合,这样a,b就撇开了关系.就可以进行join()操作了

食物链 POJ - 1182 (并查集的两种写法)

这是一个非常经典的带权并查集,有两种写法. 1 边权并查集 规定一下,当x和y这条边的权值为0时,表示x和y是同类,当为1时,表示x吃y,当为2时,表示x被y吃. 一共有三种状态,如图,当A吃B,B吃C时,C必须吃A,路径压缩后,A被C吃. 然后就是带权并查集的模板了. 判断条件,当x和y在同一颗树上是, 如果说,x和y之间的关系是0,那么x和RA与Y和RA之间的关系必须相同才行.x和Y之间的关系是1,当S[y]=2时,S[x]=1,当s[y]=1时,s[x]应等于0,才能满足 所以判断条件为(

CodeForces 510B 无向图找环的两种方法(搜索与并查集)

题目连接:http://codeforces.com/problemset/problem/510/B 解法: dfs 每次把父节点的值记录并传递下去,判断一下新达到节点: (1)没有走过 → 继续搜索: (2)走过&&不是父节点(对于本题步数也要>=4) → 找到环: 并查集 每个节点映射成 i*m+j从起点开始分别把它下面与于右面的节点加进来,如果发现有节点已经在集合中,那么环已经找到了. DFS: #include<cstdio> #include<cstdl

并查集的两种实现(按秩合并+路径压缩)

并查集:就是有求并集,查找元素属于哪个集合的功能. 1.路径压缩:使X到根上的每一个节点的父节点都变为根节点. 查询: void Find(int x) { if(a[x]==0) return x; else return a[x]=Find(a[x]); } 合并: void Merge(int x,int y) { int t1=Find(x),t2=Find(y); if(t1!=t2) a[t1]=t2; } 2.按秩合并:使较浅的树成为较深的树的子树. 查询: void Find(i