Skip to content

Commit cc363a1

Browse files
authored
Merge pull request #187 from ia7ck/uf-unite-result
[uf] unite() の返り値の情報量を増やす
2 parents 149cd89 + 1d752d6 commit cc363a1

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

libs/union_find/src/lib.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ pub struct UnionFind {
55
groups: usize,
66
}
77

8+
#[derive(Clone, Debug)]
9+
pub struct UniteResult {
10+
pub new_root: usize,
11+
pub child: usize,
12+
}
13+
814
#[derive(Clone, Copy, Debug)]
915
enum NodeKind {
1016
Root { size: usize },
@@ -61,47 +67,53 @@ impl UnionFind {
6167

6268
/// 頂点 `i` の属する連結成分と頂点 `j` の属する連結成分をつなげます。
6369
///
64-
/// 呼び出し前に別の連結成分だった場合 true を、同じ連結成分だった場合 false を返します。
70+
/// もともと `i` と `j` が同じ連結成分だった場合は `None` を返します。
6571
///
6672
/// # Examples
6773
///
6874
/// ```
6975
/// use union_find::UnionFind;
7076
/// 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());
7480
///
7581
/// // [(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());
7884
///
79-
/// assert!(uf.unite(4, 5));
85+
/// assert!(uf.unite(4, 5).is_some());
8086
/// ```
81-
pub fn unite(&mut self, i: usize, j: usize) -> bool {
87+
pub fn unite(&mut self, i: usize, j: usize) -> Option<UniteResult> {
8288
let i = self.find(i);
8389
let j = self.find(j);
8490
if i == j {
85-
return false;
91+
return None;
8692
}
8793

8894
match (self.nodes[i], self.nodes[j]) {
8995
(NodeKind::Root { size: i_size }, NodeKind::Root { size: j_size }) => {
96+
self.groups -= 1;
9097
let total = i_size + j_size;
9198
// マージテク
9299
if i_size >= j_size {
93100
self.nodes[j] = NodeKind::Child { parent: i };
94101
self.nodes[i] = NodeKind::Root { size: total };
102+
Some(UniteResult {
103+
new_root: i,
104+
child: j,
105+
})
95106
} else {
96107
self.nodes[i] = NodeKind::Child { parent: j };
97108
self.nodes[j] = NodeKind::Root { size: total };
109+
Some(UniteResult {
110+
new_root: j,
111+
child: i,
112+
})
98113
}
99114
}
100115
_ => unreachable!(),
101116
}
102-
103-
self.groups -= 1;
104-
true
105117
}
106118

107119
/// 頂点 `i` の属する連結成分のサイズ (頂点数) を返します。

0 commit comments

Comments
 (0)