@@ -7,6 +7,12 @@ pub struct Edge {
77 cost : i64 ,
88}
99
10+ #[ derive( Debug ) ]
11+ struct DSUNode {
12+ parent : i64 ,
13+ subtree_size : i64 ,
14+ }
15+
1016impl PartialEq for Edge {
1117 fn eq ( & self , other : & Self ) -> bool {
1218 self . source == other. source
@@ -27,34 +33,47 @@ impl Edge {
2733 }
2834}
2935
30- fn make_sets ( number_of_vertices : i64 ) -> Vec < i64 > {
31- let mut parent : Vec < i64 > = Vec :: with_capacity ( number_of_vertices as usize ) ;
36+ fn make_sets ( number_of_vertices : i64 ) -> Vec < DSUNode > {
37+ let mut dsu_nodes : Vec < DSUNode > = Vec :: with_capacity ( number_of_vertices as usize ) ;
3238 for i in 0 ..number_of_vertices {
33- parent. push ( i) ;
39+ dsu_nodes. push ( DSUNode {
40+ parent : i,
41+ subtree_size : 1 ,
42+ } ) ;
3443 }
35- parent
44+ dsu_nodes
3645}
3746
38- fn find ( parent : & mut Vec < i64 > , x : i64 ) -> i64 {
47+ fn find ( dsu_nodes : & mut Vec < DSUNode > , x : i64 ) -> i64 {
3948 let idx: usize = x as usize ;
40- if parent[ idx] != x {
41- parent[ idx] = find ( parent, parent[ idx] ) ;
49+ if dsu_nodes[ idx] . parent != x {
50+ dsu_nodes[ idx] . parent = find ( dsu_nodes, dsu_nodes[ idx] . parent ) ;
51+ // subtree_size of this vertex might become invalid, but only size of
52+ // roots are important and used, so it doesn't matter
4253 }
43- parent [ idx]
54+ dsu_nodes [ idx] . parent
4455}
4556
46- fn merge ( parent : & mut Vec < i64 > , x : i64 , y : i64 ) {
47- let idx_x: usize = find ( parent, x) as usize ;
48- let parent_y: i64 = find ( parent, y) ;
49- parent[ idx_x] = parent_y;
57+ fn merge ( dsu_nodes : & mut Vec < DSUNode > , x : i64 , y : i64 ) {
58+ let mut idx_x: usize = find ( dsu_nodes, x) as usize ;
59+ let mut idx_y: usize = find ( dsu_nodes, y) as usize ;
60+
61+ // We should make the smaller root a child of the other
62+ // We assume idx_x is the bigger one, and swap it if it is not
63+ if dsu_nodes[ idx_y] . subtree_size > dsu_nodes[ idx_x] . subtree_size {
64+ std:: mem:: swap ( & mut idx_y, & mut idx_x) ;
65+ }
66+
67+ dsu_nodes[ idx_y] . parent = idx_x as i64 ;
68+ dsu_nodes[ idx_x] . subtree_size += dsu_nodes[ idx_y] . subtree_size ;
5069}
5170
52- fn is_same_set ( parent : & mut Vec < i64 > , x : i64 , y : i64 ) -> bool {
53- find ( parent , x) == find ( parent , y)
71+ fn is_same_set ( dsu_nodes : & mut Vec < DSUNode > , x : i64 , y : i64 ) -> bool {
72+ find ( dsu_nodes , x) == find ( dsu_nodes , y)
5473}
5574
5675pub fn kruskal ( mut edges : Vec < Edge > , number_of_vertices : i64 ) -> ( i64 , Vec < Edge > ) {
57- let mut parent : Vec < i64 > = make_sets ( number_of_vertices) ;
76+ let mut dsu_nodes : Vec < DSUNode > = make_sets ( number_of_vertices) ;
5877
5978 edges. sort_unstable_by ( |a, b| a. cost . cmp ( & b. cost ) ) ;
6079 let mut total_cost: i64 = 0 ;
@@ -67,8 +86,8 @@ pub fn kruskal(mut edges: Vec<Edge>, number_of_vertices: i64) -> (i64, Vec<Edge>
6786
6887 let source: i64 = edge. source ;
6988 let destination: i64 = edge. destination ;
70- if !is_same_set ( & mut parent , source, destination) {
71- merge ( & mut parent , source, destination) ;
89+ if !is_same_set ( & mut dsu_nodes , source, destination) {
90+ merge ( & mut dsu_nodes , source, destination) ;
7291 merge_count += 1 ;
7392 let cost: i64 = edge. cost ;
7493 total_cost += cost;
0 commit comments