Kyopro Library
読み取り中…
検索中…
一致する文字列を見つけられません
dsu_rollback.hpp
[詳解]
1
#
pragma
once
2
#
include
"../../kyopro_library/template.hpp"
3
4
/// @brief ロールバック可能DSU
5
struct
DsuRollback
{
6
DsuRollback
()=
default
;
7
8
/// @brief コンストラクタ
9
DsuRollback
(
int
n) {
10
par.resize(n); iota(par.begin(),par.end(),0);
11
sz=vector<
int
>(n,1);
12
forest_count=n;
13
}
14
15
/// @brief 頂点 x を含む連結成分の代表元を返す
16
int
find
(
int
x) {
17
if
(par[x]==x)
return
x;
18
return
find(par[x]);
19
}
20
21
/// @brief 頂点 x と y を連結し、true を返す
22
/// @brief 既に連結されている場合は false を返す
23
bool
merge
(
int
x,
int
y) {
24
x=
find
(
x
)
; y=
find
(
y
)
;
25
if
(x==y) {
26
history.push_back({x,-1,-1,-1});
27
return
false
;
28
}
29
if
(sz[x]<sz[y]) swap(x,y);
30
history.push_back({x,y,sz[x],sz[y]});
31
par[y]=x; sz[x]+=sz[y];
32
forest_count--;
33
return
true
;
34
}
35
36
/// @brief 最後に行った連結操作を取り消す
37
void
undo
() {
38
if
(history.empty())
return
;
39
auto
[x,y,szx,szy]=history.back();
40
history.pop_back();
41
if
(y==-1)
return
;
42
par[y]=y; sz[x]=szx; sz[y]=szy;
43
}
44
45
/// @brief DSUの状態を上書き保存する
46
void
snapshot
() { history.clear(); }
47
48
/// @brief 最後に snapshot した時点まで巻き戻す
49
void
rollback
() {
while
(!history.empty())
undo
(
)
; }
50
51
/// @brief 頂点 x を含む連結成分のサイズを返す
52
int
size
(
int
x) {
return
sz[find(x)]; }
53
54
/// @brief 頂点 x と y が同じ連結成分に属するか否かを返す
55
bool
same
(
int
x,
int
y) {
return
find
(
x
)
==
find
(
y
)
; }
56
57
/// @brief 連結成分の個数を返す
58
int
count
() {
return
forest_count; }
59
60
/// @brief 各頂点を連結成分に分解する
61
vector
<
vector
<
int
>>
groups
() {
62
int
n=par.size();
63
vector<vector<
int
>> ret(n);
64
for
(
int
i=0; i<n; i++) ret[find(i)].push_back(i);
65
ret.erase(remove_if(ret.begin(),ret.end(),[&](
const
vector<
int
>& v) {
return
v.empty(); }),ret.end());
66
return
ret;
67
}
68
69
private
:
70
vector<
int
> par,sz;
71
vector<tuple<
int
,
int
,
int
,
int
>> history;
72
int
forest_count;
73
};
DsuRollback
ロールバック可能DSU
Definition
dsu_rollback.hpp:5
DsuRollback::merge
bool merge(int x, int y)
頂点 x と y を連結し、true を返す
Definition
dsu_rollback.hpp:23
DsuRollback::DsuRollback
DsuRollback()=default
DsuRollback::undo
void undo()
最後に行った連結操作を取り消す
Definition
dsu_rollback.hpp:37
DsuRollback::groups
vector< vector< int > > groups()
各頂点を連結成分に分解する
Definition
dsu_rollback.hpp:61
DsuRollback::rollback
void rollback()
最後に snapshot した時点まで巻き戻す
Definition
dsu_rollback.hpp:49
DsuRollback::same
bool same(int x, int y)
頂点 x と y が同じ連結成分に属するか否かを返す
Definition
dsu_rollback.hpp:55
DsuRollback::snapshot
void snapshot()
DSUの状態を上書き保存する
Definition
dsu_rollback.hpp:46
DsuRollback::find
int find(int x)
頂点 x を含む連結成分の代表元を返す
Definition
dsu_rollback.hpp:16
DsuRollback::DsuRollback
DsuRollback(int n)
コンストラクタ
Definition
dsu_rollback.hpp:9
DsuRollback::count
int count()
連結成分の個数を返す
Definition
dsu_rollback.hpp:58
DsuRollback::size
int size(int x)
頂点 x を含む連結成分のサイズを返す
Definition
dsu_rollback.hpp:52
graph
dsu_rollback.hpp
構築:
1.13.2