Loading [Contrib]/a11y/accessibility-menu.js
$\newcommand{\O}{\mathrm{O}}$ My Algorithm : kopricky アルゴリズムライブラリ

kopricky アルゴリズムライブラリ

Union Find

コードについての説明(個人的メモ)

Unionf Find は競技プログラミングでは基本的なアルゴリズムなので, 説明は蟻本またはこのスライドにゆずる.
各クエリの計算量は数学的には解析が難しいが, 実用上は定数と考えて問題ない.

時間計算量: Find クエリ, Union クエリ ならし $\O (\alpha(m, n))$ ($\alpha(m, n)$ は上記で定義された増加の非常にゆるやかな関数. 実用上は定数と考えて良い.)

コード

  1. class UnionFind {
  2. private:
  3. int sz;
  4. vector<int> par, size_;
  5. public:
  6. UnionFind(){}
  7. UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1){
  8. iota(par.begin(), par.end(), 0);
  9. }
  10. int find(int x){
  11. if(par[x] == x) return x;
  12. else return par[x] = find(par[x]);
  13. }
  14. void unite(int x,int y){
  15. x = find(x), y = find(y);
  16. if(x == y) return;
  17. if(size_[x] < size_[y]) swap(x,y);
  18. par[y] = x;
  19. size_[x] += size_[y];
  20. }
  21. int size(int x){
  22. x = find(x);
  23. return size_[x];
  24. }
  25. bool same(int x,int y){
  26. return find(x) == find(y);
  27. }
  28. };

おまけ

  1. class UnionFind {
  2. private:
  3. vector<int> par;
  4. public:
  5. UnionFind(){}
  6. UnionFind(const int node_size) : par(node_size){
  7. iota(par.begin(), par.end(), 0);
  8. }
  9. // 普通の path compression
  10. int find(int x){
  11. if(par[x] == x) return x;
  12. else return par[x] = find(par[x]);
  13. }
  14. // 実際に意味のある unite が行われたかどうかを返す.
  15. bool unite(int x, int y){
  16. int z;
  17. while(par[x] != par[y]){
  18. if(par[x] > par[y]) swap(x, y);
  19. z = par[x], par[x] = par[y];
  20. if(x == z) return true;
  21. x = z;
  22. }
  23. return false;
  24. }
  25. // 普通の path compression
  26. bool same(int x, int y){
  27. return find(x) == find(y);
  28. }
  29. };

verify 用の問題

AOJ : Connected Components 提出コード