-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfully_traverse.go
79 lines (69 loc) · 2.21 KB
/
fully_traverse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package problem1579
import "sort"
/*
Alice and Bob have an undirected graph of n nodes and three types of edges:
Type 1: Can be traversed by Alice only.
Type 2: Can be traversed by Bob only.
Type 3: Can be traversed by both Alice and Bob.
Given an array edges where edges[i] = [typei, ui, vi] represents a bidirectional edge of type typei between nodes ui and vi,
find the maximum number of edges you can remove so that after removing the edges,
the graph can still be fully traversed by both Alice and Bob.
The graph is fully traversed by Alice and Bob if starting from any node, they can reach all other nodes.
Return the maximum number of edges you can remove, or return -1 if Alice and Bob cannot fully traverse the graph.
*/
func maxNumEdgesToRemove(n int, edges [][]int) int {
var added, bobComp, aliceComp = 0, n, n
// Sorting by edge type
sort.Slice(edges, func(i, j int) bool { return edges[i][0] > edges[j][0] })
// Initializing disjoint sets for alice and bob
var ufAlice, ufBob = make([]int, n+1), make([]int, n+1)
for i := range ufAlice {
ufAlice[i] = i
ufBob[i] = i
}
// Adding all edges to the graph
for _, e := range edges {
var aRes, bRes int
if e[0] == 3 { // type 3, both can walk
aRes, bRes = union(ufAlice, e[1], e[2]), union(ufBob, e[1], e[2])
} else if e[0] == 2 { // type two bob can walk
bRes = union(ufBob, e[1], e[2])
} else if e[0] == 1 { // type one, alice can walk
aRes = union(ufAlice, e[1], e[2])
}
// Union returns 1 if the edges are necessary to connect
// components
if aRes > 0 {
aliceComp--
}
if bRes > 0 {
bobComp--
}
// Keep track of number of neccessary edges
added += aRes | bRes
}
// If both have 1 component, they can traverse the whole graph
if bobComp == 1 && aliceComp == 1 {
// Unnecessary edges = all edges - unnecessary edges
return len(edges) - added
}
return -1
}
// find finds the parent of x in the disjoint set
func find(uf []int, x int) int {
if uf[x] != x {
uf[x] = find(uf, uf[x])
}
return uf[x]
}
// union merges two groups in the disjoint set
func union(uf []int, x, y int) int {
var rootx, rooty int
rootx = find(uf, x)
rooty = find(uf, y)
if rootx == rooty {
return 0
}
uf[rootx] = rooty
return 1
}