Skip to content

Commit c5aeba0

Browse files
committed
feat: add Rust solution for lc No.3600
1 parent 7bf3545 commit c5aeba0

3 files changed

Lines changed: 296 additions & 1 deletion

File tree

solution/3600-3699/3600.Maximize Spanning Tree Stability with Upgrades/README.md

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ tags:
125125

126126
接下来,我们在 $[1, mn]$ 的范围内进行二分查找。我们定义一个函数 $\text{check}(lim)$ 来检查是否存在一个生成树,其稳定性至少为 $lim$。在 $\text{check}$ 函数中,我们首先将所有强度不小于 $lim$ 的边加入并查集。然后我们尝试使用升级次数来连接剩余的边,条件是边的强度至少为 $lim/2$(因为升级后强度翻倍)。如果最终并查集的连通分量数为 $1$,说明存在一个生成树满足条件。
127127

128-
时间复杂度 $O((m \times \alpha(n) + n) \times \log M)$,空间复杂度 $O(n)$。其中 $m$ 是边的数量,$n$ 是节点数量,而 $M$ 是边强度的最大值。
128+
时间复杂度 $O((m \times \alpha(n) + n) \times \log M)$,空间复杂度 $O(n)$。其中 $m$ $n$ 分别是边的数量和节点数量,而 $M$ 是边强度的最大值。
129129

130130
<!-- tabs:start -->
131131

@@ -619,6 +619,106 @@ function maxStability(n: number, edges: number[][], k: number): number {
619619
}
620620
```
621621

622+
#### Rust
623+
624+
```rust
625+
struct UnionFind {
626+
p: Vec<i32>,
627+
sz: Vec<i32>,
628+
cnt: i32,
629+
}
630+
631+
impl UnionFind {
632+
fn new(n: i32) -> Self {
633+
Self {
634+
p: (0..n).collect(),
635+
sz: vec![1; n as usize],
636+
cnt: n,
637+
}
638+
}
639+
640+
fn find(&mut self, x: i32) -> i32 {
641+
let i = x as usize;
642+
if self.p[i] != x {
643+
self.p[i] = self.find(self.p[i]);
644+
}
645+
self.p[i]
646+
}
647+
648+
fn union(&mut self, a: i32, b: i32) -> bool {
649+
let (pa, pb) = (self.find(a), self.find(b));
650+
if pa == pb {
651+
return false;
652+
}
653+
let (a, b) = (pa as usize, pb as usize);
654+
if self.sz[a] < self.sz[b] {
655+
self.p[a] = pb;
656+
self.sz[b] += self.sz[a];
657+
} else {
658+
self.p[b] = pa;
659+
self.sz[a] += self.sz[b];
660+
}
661+
self.cnt -= 1;
662+
true
663+
}
664+
}
665+
666+
impl Solution {
667+
pub fn max_stability(n: i32, edges: Vec<Vec<i32>>, k: i32) -> i32 {
668+
let mut uf = UnionFind::new(n);
669+
let mut mn = 1_000_000;
670+
671+
for e in &edges {
672+
if e[3] == 1 {
673+
mn = mn.min(e[2]);
674+
if !uf.union(e[0], e[1]) {
675+
return -1;
676+
}
677+
}
678+
}
679+
680+
for e in &edges {
681+
uf.union(e[0], e[1]);
682+
}
683+
684+
if uf.cnt > 1 {
685+
return -1;
686+
}
687+
688+
let check = |lim: i32| {
689+
let mut uf = UnionFind::new(n);
690+
691+
for e in &edges {
692+
if e[2] >= lim {
693+
uf.union(e[0], e[1]);
694+
}
695+
}
696+
697+
let mut rem = k;
698+
for e in &edges {
699+
if rem > 0 && e[2] * 2 >= lim && uf.union(e[0], e[1]) {
700+
rem -= 1;
701+
}
702+
}
703+
704+
uf.cnt == 1
705+
};
706+
707+
let (mut l, mut r) = (1, mn);
708+
while l < r {
709+
let mid = (l + r + 1) >> 1;
710+
if check(mid) {
711+
l = mid;
712+
} else {
713+
r = mid - 1;
714+
}
715+
}
716+
717+
l
718+
}
719+
}
720+
```
721+
622722
<!-- tabs:end -->
623723

624724
<!-- solution:end -->

solution/3600-3699/3600.Maximize Spanning Tree Stability with Upgrades/README_EN.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,106 @@ function maxStability(n: number, edges: number[][], k: number): number {
610610
}
611611
```
612612

613+
#### Rust
614+
615+
```rust
616+
struct UnionFind {
617+
p: Vec<i32>,
618+
sz: Vec<i32>,
619+
cnt: i32,
620+
}
621+
622+
impl UnionFind {
623+
fn new(n: i32) -> Self {
624+
Self {
625+
p: (0..n).collect(),
626+
sz: vec![1; n as usize],
627+
cnt: n,
628+
}
629+
}
630+
631+
fn find(&mut self, x: i32) -> i32 {
632+
let i = x as usize;
633+
if self.p[i] != x {
634+
self.p[i] = self.find(self.p[i]);
635+
}
636+
self.p[i]
637+
}
638+
639+
fn union(&mut self, a: i32, b: i32) -> bool {
640+
let (pa, pb) = (self.find(a), self.find(b));
641+
if pa == pb {
642+
return false;
643+
}
644+
let (a, b) = (pa as usize, pb as usize);
645+
if self.sz[a] < self.sz[b] {
646+
self.p[a] = pb;
647+
self.sz[b] += self.sz[a];
648+
} else {
649+
self.p[b] = pa;
650+
self.sz[a] += self.sz[b];
651+
}
652+
self.cnt -= 1;
653+
true
654+
}
655+
}
656+
657+
impl Solution {
658+
pub fn max_stability(n: i32, edges: Vec<Vec<i32>>, k: i32) -> i32 {
659+
let mut uf = UnionFind::new(n);
660+
let mut mn = 1_000_000;
661+
662+
for e in &edges {
663+
if e[3] == 1 {
664+
mn = mn.min(e[2]);
665+
if !uf.union(e[0], e[1]) {
666+
return -1;
667+
}
668+
}
669+
}
670+
671+
for e in &edges {
672+
uf.union(e[0], e[1]);
673+
}
674+
675+
if uf.cnt > 1 {
676+
return -1;
677+
}
678+
679+
let check = |lim: i32| {
680+
let mut uf = UnionFind::new(n);
681+
682+
for e in &edges {
683+
if e[2] >= lim {
684+
uf.union(e[0], e[1]);
685+
}
686+
}
687+
688+
let mut rem = k;
689+
for e in &edges {
690+
if rem > 0 && e[2] * 2 >= lim && uf.union(e[0], e[1]) {
691+
rem -= 1;
692+
}
693+
}
694+
695+
uf.cnt == 1
696+
};
697+
698+
let (mut l, mut r) = (1, mn);
699+
while l < r {
700+
let mid = (l + r + 1) >> 1;
701+
if check(mid) {
702+
l = mid;
703+
} else {
704+
r = mid - 1;
705+
}
706+
}
707+
708+
l
709+
}
710+
}
711+
```
712+
613713
<!-- tabs:end -->
614714

615715
<!-- solution:end -->
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
struct UnionFind {
2+
p: Vec<i32>,
3+
sz: Vec<i32>,
4+
cnt: i32,
5+
}
6+
7+
impl UnionFind {
8+
fn new(n: i32) -> Self {
9+
Self {
10+
p: (0..n).collect(),
11+
sz: vec![1; n as usize],
12+
cnt: n,
13+
}
14+
}
15+
16+
fn find(&mut self, x: i32) -> i32 {
17+
let i = x as usize;
18+
if self.p[i] != x {
19+
self.p[i] = self.find(self.p[i]);
20+
}
21+
self.p[i]
22+
}
23+
24+
fn union(&mut self, a: i32, b: i32) -> bool {
25+
let (pa, pb) = (self.find(a), self.find(b));
26+
if pa == pb {
27+
return false;
28+
}
29+
let (a, b) = (pa as usize, pb as usize);
30+
if self.sz[a] < self.sz[b] {
31+
self.p[a] = pb;
32+
self.sz[b] += self.sz[a];
33+
} else {
34+
self.p[b] = pa;
35+
self.sz[a] += self.sz[b];
36+
}
37+
self.cnt -= 1;
38+
true
39+
}
40+
}
41+
42+
impl Solution {
43+
pub fn max_stability(n: i32, edges: Vec<Vec<i32>>, k: i32) -> i32 {
44+
let mut uf = UnionFind::new(n);
45+
let mut mn = 1_000_000;
46+
47+
for e in &edges {
48+
if e[3] == 1 {
49+
mn = mn.min(e[2]);
50+
if !uf.union(e[0], e[1]) {
51+
return -1;
52+
}
53+
}
54+
}
55+
56+
for e in &edges {
57+
uf.union(e[0], e[1]);
58+
}
59+
60+
if uf.cnt > 1 {
61+
return -1;
62+
}
63+
64+
let check = |lim: i32| {
65+
let mut uf = UnionFind::new(n);
66+
67+
for e in &edges {
68+
if e[2] >= lim {
69+
uf.union(e[0], e[1]);
70+
}
71+
}
72+
73+
let mut rem = k;
74+
for e in &edges {
75+
if rem > 0 && e[2] * 2 >= lim && uf.union(e[0], e[1]) {
76+
rem -= 1;
77+
}
78+
}
79+
80+
uf.cnt == 1
81+
};
82+
83+
let (mut l, mut r) = (1, mn);
84+
while l < r {
85+
let mid = (l + r + 1) >> 1;
86+
if check(mid) {
87+
l = mid;
88+
} else {
89+
r = mid - 1;
90+
}
91+
}
92+
93+
l
94+
}
95+
}

0 commit comments

Comments
 (0)