package template // UnionFind defind // 路径压缩 + 秩优化 type UnionFind struct { parent, rank []int count int } // Init define func (uf *UnionFind) Init(n int) { uf.count = n uf.parent = make([]int, n) uf.rank = make([]int, n) for i := range uf.parent { uf.parent[i] = i } } // Find define func (uf *UnionFind) Find(p int) int { root := p for root != uf.parent[root] { root = uf.parent[root] } // compress path for p != uf.parent[p] { tmp := uf.parent[p] uf.parent[p] = root p = tmp } return root } // Union define func (uf *UnionFind) Union(p, q int) { proot := uf.Find(p) qroot := uf.Find(q) if proot == qroot { return } if uf.rank[qroot] > uf.rank[proot] { uf.parent[proot] = qroot } else { uf.parent[qroot] = proot if uf.rank[proot] == uf.rank[qroot] { uf.rank[proot]++ } } uf.count-- } // TotalCount define func (uf *UnionFind) TotalCount() int { return uf.count } // UnionFindCount define // 计算每个集合中元素的个数 + 最大集合元素个数 type UnionFindCount struct { parent, count []int maxUnionCount int } // Init define func (uf *UnionFindCount) Init(n int) { uf.parent = make([]int, n) uf.count = make([]int, n) for i := range uf.parent { uf.parent[i] = i uf.count[i] = 1 } } // Find define func (uf *UnionFindCount) Find(p int) int { root := p for root != uf.parent[root] { root = uf.parent[root] } return root } // 不进行秩压缩,时间复杂度爆炸,太高了 // func (uf *UnionFindCount) union(p, q int) { // proot := uf.find(p) // qroot := uf.find(q) // if proot == qroot { // return // } // if proot != qroot { // uf.parent[proot] = qroot // uf.count[qroot] += uf.count[proot] // } // } // Union define func (uf *UnionFindCount) Union(p, q int) { proot := uf.Find(p) qroot := uf.Find(q) if proot == qroot { return } if proot == len(uf.parent)-1 { //proot is root } else if qroot == len(uf.parent)-1 { // qroot is root, always attach to root proot, qroot = qroot, proot } else if uf.count[qroot] > uf.count[proot] { proot, qroot = qroot, proot } //set relation[0] as parent uf.maxUnionCount = max(uf.maxUnionCount, (uf.count[proot] + uf.count[qroot])) uf.parent[qroot] = proot uf.count[proot] += uf.count[qroot] } // Count define func (uf *UnionFindCount) Count() []int { return uf.count } // MaxUnionCount define func (uf *UnionFindCount) MaxUnionCount() int { return uf.maxUnionCount } func max(a int, b int) int { if a > b { return a } return b }