@@ -5,6 +5,12 @@ pub struct UnionFind {
5
5
groups : usize ,
6
6
}
7
7
8
+ #[ derive( Clone , Debug ) ]
9
+ pub struct UniteResult {
10
+ pub new_root : usize ,
11
+ pub child : usize ,
12
+ }
13
+
8
14
#[ derive( Clone , Copy , Debug ) ]
9
15
enum NodeKind {
10
16
Root { size : usize } ,
@@ -61,47 +67,53 @@ impl UnionFind {
61
67
62
68
/// 頂点 `i` の属する連結成分と頂点 `j` の属する連結成分をつなげます。
63
69
///
64
- /// 呼び出し前に別の連結成分だった場合 true を、同じ連結成分だった場合 false を返します。
70
+ /// もともと `i` と `j` が同じ連結成分だった場合は `None` を返します。
65
71
///
66
72
/// # Examples
67
73
///
68
74
/// ```
69
75
/// use union_find::UnionFind;
70
76
/// let mut uf = UnionFind::new(6);
71
- /// assert!(uf.unite(0, 1));
72
- /// assert!(uf.unite(1, 2));
73
- /// assert!(uf.unite(3, 4));
77
+ /// assert!(uf.unite(0, 1).is_some() );
78
+ /// assert!(uf.unite(1, 2).is_some() );
79
+ /// assert!(uf.unite(3, 4).is_some() );
74
80
///
75
81
/// // [(0, 1, 2), (3, 4), (5)]
76
- /// assert!(! uf.unite(0, 2));
77
- /// assert!(! uf.unite(3, 3));
82
+ /// assert!(uf.unite(0, 2).is_none( ));
83
+ /// assert!(uf.unite(3, 3).is_none( ));
78
84
///
79
- /// assert!(uf.unite(4, 5));
85
+ /// assert!(uf.unite(4, 5).is_some() );
80
86
/// ```
81
- pub fn unite ( & mut self , i : usize , j : usize ) -> bool {
87
+ pub fn unite ( & mut self , i : usize , j : usize ) -> Option < UniteResult > {
82
88
let i = self . find ( i) ;
83
89
let j = self . find ( j) ;
84
90
if i == j {
85
- return false ;
91
+ return None ;
86
92
}
87
93
88
94
match ( self . nodes [ i] , self . nodes [ j] ) {
89
95
( NodeKind :: Root { size : i_size } , NodeKind :: Root { size : j_size } ) => {
96
+ self . groups -= 1 ;
90
97
let total = i_size + j_size;
91
98
// マージテク
92
99
if i_size >= j_size {
93
100
self . nodes [ j] = NodeKind :: Child { parent : i } ;
94
101
self . nodes [ i] = NodeKind :: Root { size : total } ;
102
+ Some ( UniteResult {
103
+ new_root : i,
104
+ child : j,
105
+ } )
95
106
} else {
96
107
self . nodes [ i] = NodeKind :: Child { parent : j } ;
97
108
self . nodes [ j] = NodeKind :: Root { size : total } ;
109
+ Some ( UniteResult {
110
+ new_root : j,
111
+ child : i,
112
+ } )
98
113
}
99
114
}
100
115
_ => unreachable ! ( ) ,
101
116
}
102
-
103
- self . groups -= 1 ;
104
- true
105
117
}
106
118
107
119
/// 頂点 `i` の属する連結成分のサイズ (頂点数) を返します。
0 commit comments