go: add «1579. Remove Max Number of Edges to Keep Graph Fully Traversable»
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
92c5bae5aa
commit
5bb1c156a4
1 changed files with 104 additions and 0 deletions
104
go/remove-max-number-of-edges-to-keep-graph-fully-traversable.go
Normal file
104
go/remove-max-number-of-edges-to-keep-graph-fully-traversable.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type UnionFind struct {
|
||||
parent []int
|
||||
rank []int
|
||||
count int
|
||||
}
|
||||
|
||||
func (uf *UnionFind) Count() int {
|
||||
return uf.count
|
||||
}
|
||||
|
||||
func (uf *UnionFind) find(u int) int {
|
||||
if uf.parent[u] != u {
|
||||
uf.parent[u] = uf.find(uf.parent[u])
|
||||
}
|
||||
|
||||
return uf.parent[u]
|
||||
}
|
||||
|
||||
func (uf *UnionFind) Union(u, v int) bool {
|
||||
rootU := uf.find(u)
|
||||
rootV := uf.find(v)
|
||||
|
||||
if rootU == rootV {
|
||||
return false
|
||||
}
|
||||
|
||||
if uf.rank[rootU] > uf.rank[rootV] {
|
||||
uf.parent[rootV] = rootU
|
||||
} else if uf.rank[rootU] < uf.rank[rootV] {
|
||||
uf.parent[rootU] = rootV
|
||||
} else {
|
||||
uf.parent[rootV] = rootU
|
||||
uf.rank[rootU]++
|
||||
}
|
||||
|
||||
uf.count--
|
||||
return true
|
||||
}
|
||||
|
||||
func makeUnionFind(n int) UnionFind {
|
||||
parent := make([]int, n)
|
||||
for i := range n {
|
||||
parent[i] = i
|
||||
}
|
||||
|
||||
return UnionFind{
|
||||
parent: parent,
|
||||
rank: make([]int, n),
|
||||
count: n,
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
Alice int = 1
|
||||
Bob = 2
|
||||
Both = 3
|
||||
)
|
||||
|
||||
// by edge type — preferring «Both» type
|
||||
func byEdgeType(l, r []int) int {
|
||||
return -cmp.Compare(l[0], r[0])
|
||||
}
|
||||
|
||||
func maxNumEdgesToRemove(n int, edges [][]int) int {
|
||||
slices.SortFunc(edges, byEdgeType)
|
||||
|
||||
alice := makeUnionFind(n)
|
||||
bob := makeUnionFind(n)
|
||||
|
||||
added := 0
|
||||
for _, edge := range edges {
|
||||
t, u, v := edge[0], edge[1]-1, edge[2]-1
|
||||
|
||||
switch t {
|
||||
case Alice:
|
||||
if alice.Union(u, v) {
|
||||
added++
|
||||
}
|
||||
case Bob:
|
||||
if bob.Union(u, v) {
|
||||
added++
|
||||
}
|
||||
case Both:
|
||||
connectsAlice := alice.Union(u, v)
|
||||
connectsBob := bob.Union(u, v)
|
||||
if connectsAlice || connectsBob {
|
||||
added++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if alice.Count() > 1 || bob.Count() > 1 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return len(edges) - added
|
||||
}
|
Loading…
Reference in a new issue