并查集
首先来明确一下概念,并查集是一种树,主要操作是合并两个集合 以及查询两个结点是否在一个集合中.
虽然这么说但是我总是觉得这是种很奇葩的树.
路径压缩好的并查集的树一般长这样:

对没错就是这样,我没有恶搞,中间是父节点,一圈都是子结点.
这样查询的时候很容易就能判断两个结点是否在一个集合中了(如果两个结点父节点是同一个那么他们就处在一个集合中,反之则不在一个集合中).
并查集最重要路径压缩操作,就是把这个结点父指针指向这个数的根.
public class unionFindSet {
public static void main(String[] args) {
int n = 100;
node[] nodes = new node[100];
for (int i = 0; i < n; i++) {
nodes[i] = new node();
nodes[i].data = i;
nodes[i].parent = nodes[i];
}
union(nodes[1], nodes[2]);
}
static node findzip(node n) {
n.parent = find(n);
return n.parent;
}
static node find(node n) {
if (n.parent == n)
return n;
return find(n.parent);
}
static void union(node n, node m) {
node nparent = findzip(n);
node mparent = findzip(m);
mparent.parent = nparent;
}
static class node {
int data;
node parent;
}
}
最近见到一个bilibili的题:
全宇宙魔法少女大聚会(数量较多),如果魔法少女A和魔法少女B存在羁绊,魔法少女B和魔法少女C存在羁绊,那么魔法少女A和魔法少女C也存在羁绊;所有有羁绊关系的魔法少女形成一个结界,请计算有多少个结界并计算各个结界中的人数。
这道题用并查集就很简单,
import java.util.*;
/**
* 使用并查集把结界建好.
* 然后用Map统计每个结界中有多少个马猴烧酒
* Map的大小就是结界的数量
*/
public class UnionFindSet {
public static void main(String[] args) {
int n = 100000;//假设100000个马猴烧酒
Random random = new Random();
node[] nodes = new node[n];
Map<node, Integer> map = new HashMap<>();
for (int i = 0; i < nodes.length; i++) {
nodes[i] = new node();
nodes[i].data = random.nextInt(n);//假设100000个马猴烧酒随机存在羁绊
nodes[i].parent = nodes[i];//初始化它的父指针指向自身
}
for (int i = 0; i < nodes.length; i++) {
union(nodes[i], nodes[nodes[i].data]);//建立并查集
}
for (int i = 0; i < nodes.length; i++) {
node node = findzip(nodes[i]);
if (map.containsKey(node)) {
Integer num = map.get(node) + 1;
map.put(node, num);
} else {
map.put(node, 1);
}
}
System.out.println("共有结界数量: "+map.size());
Set<node> set = map.keySet();
for (node node : set) {
System.out.println("这个结界有马猴烧酒: "+map.get(node));
}
}
static node findzip(node n) {
n.parent = find(n);
return n.parent;
}
static node find(node n) {
if (n.parent == n)
return n;
return find(n.parent);
}
static void union(node n, node m) {
node nparent = findzip(n);
node mparent = findzip(m);
mparent.parent = nparent;
}
static class node {
int data;
node parent;
}
}

浙公网安备 33010602011771号