-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.swift
88 lines (81 loc) · 2.2 KB
/
1489-find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree.swift
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
80
81
82
83
84
85
86
87
88
/**
* Question Link: https://leetcode.com/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/
*/
class UnionFind {
var par: [Int] = []
var rank: [Int] = []
init(_ n: Int) {
par = [Int](0..<n)
rank = [Int](repeating: 1, count: n)
}
func find(_ v1: Int) -> Int {
var v1 = v1
while v1 != par[v1] {
par[v1] = par[par[v1]]
v1 = par[v1]
}
return v1
}
func union(_ v1: Int, _ v2: Int) -> Bool {
var p1 = find(v1)
var p2 = find(v2)
if p1 == p2 {
return false
}
if rank[p1] > rank[p2] {
par[p2] = p1
rank[p1] += rank[p2]
} else {
par[p1] = p2
rank[p2] += rank[p1]
}
return true
}
}
class Solution {
func findCriticalAndPseudoCriticalEdges(_ n: Int, _ edges: [[Int]]) -> [[Int]] {
var edges = edges
for i in 0..<edges.count {
edges[i].append(i)
}
edges.sort { $0[2] < $1[2] }
var mstWeight = 0
var uf = UnionFind(n)
for e in edges {
let v1 = e[0], v2 = e[1], w = e[2]
if uf.union(v1, v2) {
mstWeight += w
}
}
var critical = [Int]()
var pseudo = [Int]()
for e in edges {
let n1 = e[0], n2 = e[1], eWeight = e[2], i = e[3]
var weight = 0
var uf = UnionFind(n)
for ed in edges {
let v1 = ed[0], v2 = ed[1], w = ed[2], j = ed[3]
if i != j && uf.union(v1, v2) {
weight += w
}
}
if uf.rank.max() != n || weight > mstWeight {
critical.append(i)
continue
}
let uf2 = UnionFind(n)
uf2.union(n1, n2)
weight = eWeight
for ed in edges {
let v1 = ed[0], v2 = ed[1], w = ed[2]
if uf2.union(v1, v2) {
weight += w
}
}
if weight == mstWeight {
pseudo.append(i)
}
}
return [critical, pseudo]
}
}