-
Notifications
You must be signed in to change notification settings - Fork 0
/
1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.kt
67 lines (59 loc) · 1.87 KB
/
1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.kt
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
class Solution {
class UnionFind(val n: Int) {
val par = IntArray (n) { it }
val rank = IntArray (n) { 1 }
fun find(x: Int): Int {
if (par[x] != x)
par[x] = find(par[x])
return par[x]
}
fun union(x: Int, y: Int): Boolean {
val px = find(x)
val py = find(y)
if (px == py) return false
if (rank[px] > rank[py]) {
par[py] = px
rank[px] += rank[py]
} else {
par[px] = py
rank[py] += rank[px]
}
return true
}
}
fun findCriticalAndPseudoCriticalEdges(n: Int, _edges: Array<IntArray>): List<List<Int>> {
val edges = _edges.mapIndexed { i, v ->
intArrayOf(v[0], v[1], v[2], i)
}.sortedWith(
Comparator { a, b ->
a[2] - b[2]
}
)
var mstWeight = 0
val uf = UnionFind (n)
for ((u, v, w, i) in edges) {
if (uf.union(u, v)) mstWeight += w
}
val crit = mutableListOf<Int>()
val pseudo = mutableListOf<Int>()
for ((u, v, w, i) in edges) {
val uf2 = UnionFind (n)
var mstWeightWithout = 0
for ((u2, v2, w2, i2) in edges) {
if (i != i2 && uf2.union(u2, v2)) mstWeightWithout += w2
}
if (uf2.rank.max()!! != n || mstWeightWithout > mstWeight) {
crit.add(i)
continue
}
val uf3 = UnionFind (n)
uf3.union(u, v)
var mstWeightWith = w
for ((u3, v3, w3, i3) in edges) {
if (uf3.union(u3, v3)) mstWeightWith += w3
}
if (mstWeightWith == mstWeight) pseudo.add(i)
}
return listOf(crit, pseudo)
}
}