Skip to content

Commit 2ad461f

Browse files
committed
增加 UnionFind 模板
1 parent 8cbf142 commit 2ad461f

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

Topics/Union_Find.png

254 KB
Loading

template/UnionFind.go

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package template
2+
3+
// UnionFind defind
4+
// 路径压缩 + 秩优化
5+
type UnionFind struct {
6+
parent, rank []int
7+
count int
8+
}
9+
10+
// Init define
11+
func (uf *UnionFind) Init(n int) {
12+
uf.count = n
13+
uf.parent = make([]int, n)
14+
uf.rank = make([]int, n)
15+
for i := range uf.parent {
16+
uf.parent[i] = i
17+
}
18+
}
19+
20+
// Find define
21+
func (uf *UnionFind) Find(p int) int {
22+
root := p
23+
for root != uf.parent[root] {
24+
root = uf.parent[root]
25+
}
26+
// compress path
27+
for p != uf.parent[p] {
28+
tmp := uf.parent[p]
29+
uf.parent[p] = root
30+
p = tmp
31+
}
32+
return root
33+
}
34+
35+
// Union define
36+
func (uf *UnionFind) Union(p, q int) {
37+
proot := uf.Find(p)
38+
qroot := uf.Find(q)
39+
if proot == qroot {
40+
return
41+
}
42+
if uf.rank[qroot] > uf.rank[proot] {
43+
uf.parent[proot] = qroot
44+
} else {
45+
uf.parent[qroot] = proot
46+
if uf.rank[proot] == uf.rank[qroot] {
47+
uf.rank[proot]++
48+
}
49+
}
50+
uf.count--
51+
}
52+
53+
// TotalCount define
54+
func (uf *UnionFind) TotalCount() int {
55+
return uf.count
56+
}
57+
58+
// UnionFindCount define
59+
// 计算每个集合中元素的个数 + 最大集合元素个数
60+
type UnionFindCount struct {
61+
parent, count []int
62+
maxUnionCount int
63+
}
64+
65+
// Init define
66+
func (uf *UnionFindCount) Init(n int) {
67+
uf.parent = make([]int, n)
68+
uf.count = make([]int, n)
69+
for i := range uf.parent {
70+
uf.parent[i] = i
71+
uf.count[i] = 1
72+
}
73+
}
74+
75+
// Find define
76+
func (uf *UnionFindCount) Find(p int) int {
77+
root := p
78+
for root != uf.parent[root] {
79+
root = uf.parent[root]
80+
}
81+
return root
82+
}
83+
84+
// 不进行秩压缩,时间复杂度爆炸,太高了
85+
// func (uf *UnionFindCount) union(p, q int) {
86+
// proot := uf.find(p)
87+
// qroot := uf.find(q)
88+
// if proot == qroot {
89+
// return
90+
// }
91+
// if proot != qroot {
92+
// uf.parent[proot] = qroot
93+
// uf.count[qroot] += uf.count[proot]
94+
// }
95+
// }
96+
97+
// Union define
98+
func (uf *UnionFindCount) Union(p, q int) {
99+
proot := uf.Find(p)
100+
qroot := uf.Find(q)
101+
if proot == qroot {
102+
return
103+
}
104+
if proot == len(uf.parent)-1 {
105+
//proot is root
106+
} else if qroot == len(uf.parent)-1 {
107+
// qroot is root, always attach to root
108+
proot, qroot = qroot, proot
109+
} else if uf.count[qroot] > uf.count[proot] {
110+
proot, qroot = qroot, proot
111+
}
112+
113+
//set relation[0] as parent
114+
uf.maxUnionCount = max(uf.maxUnionCount, (uf.count[proot] + uf.count[qroot]))
115+
uf.parent[qroot] = proot
116+
uf.count[proot] += uf.count[qroot]
117+
}
118+
119+
// Count define
120+
func (uf *UnionFindCount) Count() []int {
121+
return uf.count
122+
}
123+
124+
// MaxUnionCount define
125+
func (uf *UnionFindCount) MaxUnionCount() int {
126+
return uf.maxUnionCount
127+
}
128+
129+
func max(a int, b int) int {
130+
if a > b {
131+
return a
132+
}
133+
return b
134+
}

0 commit comments

Comments
 (0)