Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
dsu_merging.hpp
[詳解]
1#include "../../kyopro_library/template.hpp"
2
4 using Type=ll;
5 static Type op(Type a, Type b) { return a+b; }
6};
7
8/// @brief 値をマージする DSU
9/// @tparam Semigroup 半群
10template<typename Semigroup=DsuBaseSemigroup>
11struct DsuMerging {
12 using Type=typename Semigroup::Type;
13 DsuMerging()=default;
14
15 /// @brief コンストラクタ
16 DsuMerging(int n, const vector<Type>& v) {
17 par.resize(n); iota(par.begin(),par.end(),0);
18 sz=vector<int>(n,1);
19 dat=v;
20 forest_count=n;
21 }
22
23 /// @brief 頂点 x を含む連結成分の代表元を返す
24 /// @note O(α(N))
25 int find(int x) {
26 if(par[x]==x) return x;
27 return par[x]=find(par[x]);
28 }
29
30 /// @brief 頂点 x と y を連結し、true を返す
31 /// @brief 既に連結されている場合は false を返す
32 /// @note O(α(N))
33 bool merge(int x, int y) {
34 x=find(x); y=find(y);
35 if(x==y) return false;
36 if(sz[x]>=sz[y]) {
37 par[y]=x; sz[x]+=sz[y];
38 dat[x]=Semigroup::op(dat[x],dat[y]);
39 } else {
40 par[x]=y; sz[y]+=sz[x];
41 dat[y]=Semigroup::op(dat[x],dat[y]);
42 }
43 forest_count--;
44 return true;
45 }
46
47 /// @brief 頂点 x を含む連結成分の半群積を返す
48 const Type& get(int x) { return dat[find(x)]; }
49
50 /// @brief 頂点 x を含む連結成分のサイズを返す
51 int size(int x) const { return sz[find(x)]; }
52
53 /// @brief 頂点 x と y が同じ連結成分に属するか否かを返す
54 bool same(int x, int y) const {return find(x)==find(y);}
55
56 /// @brief 連結成分の個数を返す
57 int count() const { return forest_count; }
58
59 /// @brief 各頂点を連結成分に分解する
60 vector<vector<int>> groups() const {
61 int n=par.size();
62 vector<vector<int>> ret(n);
63 for(int i=0; i<n; i++) ret[find(i)].push_back(i);
64 ret.erase(remove_if(ret.begin(),ret.end(),[&](const vector<int>& v) { return v.empty(); }),ret.end());
65 return ret;
66 }
67
68private:
69 vector<int> par,sz;
70 vector<Type> dat;
71 int forest_count;
72};
static Type op(Type a, Type b)
値をマージする DSU
DsuMerging(int n, const vector< Type > &v)
コンストラクタ
bool same(int x, int y) const
頂点 x と y が同じ連結成分に属するか否かを返す
DsuMerging()=default
vector< vector< int > > groups() const
各頂点を連結成分に分解する
int count() const
連結成分の個数を返す
const Type & get(int x)
頂点 x を含む連結成分の半群積を返す
int size(int x) const
頂点 x を含む連結成分のサイズを返す
bool merge(int x, int y)
頂点 x と y を連結し、true を返す
int find(int x)
頂点 x を含む連結成分の代表元を返す