SlideShare a Scribd company logo
Union-Find
(素集合データ構造)
• グループ分けを管理する
• はじめ,𝑛 個の物は全て別々のグループ
• 次の 2 種類のクエリに対応する
1. 「まとめる」
2. 「判定」
Union-Find 木の機能
1 2 3 4 5
クエリ 1:まとめる
• 2 つのグループを 1 つにまとめる
1 2
1 2
1 3 2 4 6
1 2 3 4 6
クエリ 2:判定
• 2 つの要素が同じグループに属しているかを判
定する
1 3 2 4 6 5
1 と 3 → true
1 と 2 → false
素朴な実現法 (1/2)
• 配列に,同じグループなら同じ数字を入れてお
く
1 3 2 4 6 5
1 2 3 4 5 6
1 2 1 2 5 2
素朴な実現法 (2/2)
• この方針の問題点
– グループをまとめる際に,𝑂(𝑛) 時間かかってしまう
– 実際には,この方針でも少しの工夫でならし 𝑂(log 𝑛) 時間にできます
http://topcoder.g.hatena.ne.jp/iwiwi/20131226/1388062106
• Union-Find 木は,もっと効率的に行う
Union-Find 木
• グループを,1 つの木で表現する
– したがって,全体では森
1 3 2 4 6 5
1
3
2
4 6
5
クエリ1:「まとめる」
• 片方の木の根からもう片方の根に辺を張ればよ
い
1 2
1
2
1
3
2
4 6
1
3
2
4 6
1 と 2 をまとめる
2 から 1 に辺を張る
クエリ2:「判定」
• 2 つの要素を上に辿って,根が同じかどうかを
見ればよい
1
3
2
4 6
5
2 と 6 → 根は共に 2 → true
1 と 4 → 根は 1 と 2 → false
Union-Find 木の効率
• 正当性:このやり方で,グループの判定はうま
くできる
• 効率:最悪の場合,この方法でも
ツリーが縦長になると処理が遅く
なってしまう
→ 効率化のテクニックを導入
効率化工夫 1:経路圧縮
• 上向きに辿って再帰的に根を調べる際に,調べ
たら辺を根に直接つなぎ直す
• 4 の根を調べると,2, 3, 4 の根が 1 と分かる
1
2
3
4
1
2 3 4
効率化工夫 2:ランク
• 木の高さを持っておき,低い方を高い方に繋げ
るようにする
• ただし,経路圧縮と組み合わせた際,経路圧縮による高
さの減少は無視する
(つまり,ランクは経路圧縮しなかった場合の高さに相当する)
1
2
3
4
5
1
2
3
4
5
ランク 3 ランク 2 ランク 3
Union-Find 木の計算量
• 2 つの工夫の両方をして 𝑂(𝛼(𝑛))
– 𝛼(𝑛) はアッカーマン関数 𝐴(𝑛, 𝑛) の逆関数
– 相当小さい(log より小さい!)
• 片方だけでも,だいたい 𝑂(log 𝑛)
– 経路圧縮のみが実装が楽でよい
• これらはならし計算量
Union-Find 木の実装(ランク無し)
• 経路圧縮のみ(ランクは使わない)
• par[i] = i ならば根
– はじめは全部の頂点が根
int par[MAX_N]; // 親の番号
// n 要素で初期化
void init(int n) {
for (int i = 0; i < n; i++) par[i] = i;
}
// 木の根を求める
int root(int x) {
if (par[x] == x) { // 根
return x;
} else {
return par[x] = root(par[x]); // 経路圧縮
}
}
// x と y が同じ集合に属するか否か
bool same(int x, int y) {
return root(x) == root(y);
}
Union-Find 木の実装(ランク無し)
// x と y の属する集合を併合
void unite(int x, int y) {
x = root(x);
y = root(y);
if (x == y) return;
par[x] = y;
}
Union-Find 木の実装(ランク無し)
Union-Find 木の実装(ランク有り)
int par[MAX_N], rank[MAX_N];
void init(int n) {
for (int i = 0; i < n; i++) {
par[i] = i;
rank[i] = 0;
}
}
int root(int x) {
return par[x] == x ? x : par[x] =
root(par[x]);
}
bool same(int x, int y) {
return root(x) == root(y);
}
void unite(int x, int y) {
x = root(x);
y = root(y);
if (x == y) return;
if (rank[x] < rank[y]) {
par[x] = y;
} else {
par[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
補足
• Union-Find 木はグループをまとめることはでき
ても,分割することはできない
重要な制約
• Union-Find 木を改造して機能を付加することが
必要になるような問題もあります

More Related Content

What's hot

様々な全域木問題
様々な全域木問題様々な全域木問題
様々な全域木問題
tmaehara
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
okuraofvegetable
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
Yoichi Iwata
 
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
Kensuke Otsuki
 
図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』
Proktmr
 
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムTakuya Akiba
 
Fractional cascading
Fractional cascadingFractional cascading
Fractional cascading
Nariaki Tateiwa
 
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
Kensuke Otsuki
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
Masaki Hara
 
深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし
AtCoder Inc.
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
Masahiro Sakai
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説
AtCoder Inc.
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説
AtCoder Inc.
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとはTakuya Akiba
 
Rolling hash
Rolling hashRolling hash
Convex Hull Trick
Convex Hull TrickConvex Hull Trick
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
AtCoder Inc.
 
双対性
双対性双対性
双対性
Yoichi Iwata
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
Nagisa Eto
 

What's hot (20)

様々な全域木問題
様々な全域木問題様々な全域木問題
様々な全域木問題
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
 
Binary indexed tree
Binary indexed treeBinary indexed tree
Binary indexed tree
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
 
図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』
 
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズム
 
Fractional cascading
Fractional cascadingFractional cascading
Fractional cascading
 
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
 
Rolling hash
Rolling hashRolling hash
Rolling hash
 
Convex Hull Trick
Convex Hull TrickConvex Hull Trick
Convex Hull Trick
 
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
 
双対性
双対性双対性
双対性
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
 

Viewers also liked

【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス
【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス
【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス
Unity Technologies Japan K.K.
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
Yoshifumi Kawai
 
幾何コンテスト2013
幾何コンテスト2013幾何コンテスト2013
幾何コンテスト2013Naoto Mizuno
 
AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説
AtCoder Inc.
 
素集合データ構造
素集合データ構造素集合データ構造
素集合データ構造
京大 マイコンクラブ
 
AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説
AtCoder Inc.
 
AtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組みAtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組み
AtCoder Inc.
 
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
AtCoder Inc.
 
TCO2017R1
TCO2017R1TCO2017R1
TCO2017R1
AtCoder Inc.
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
shindannin
 
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
Unity Technologies Japan K.K.
 

Viewers also liked (11)

【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス
【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス
【Unite 2017 Tokyo】パフォーマンス向上のためのスクリプトのベストプラクティス
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
 
幾何コンテスト2013
幾何コンテスト2013幾何コンテスト2013
幾何コンテスト2013
 
AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説
 
素集合データ構造
素集合データ構造素集合データ構造
素集合データ構造
 
AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説
 
AtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組みAtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組み
 
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
 
TCO2017R1
TCO2017R1TCO2017R1
TCO2017R1
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
 
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
 

More from AtCoder Inc.

Square869120 contest #2
Square869120 contest #2Square869120 contest #2
Square869120 contest #2
AtCoder Inc.
 
Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説
Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説
Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説
AtCoder Inc.
 
Chokudai Contest 001
Chokudai Contest 001Chokudai Contest 001
Chokudai Contest 001
AtCoder Inc.
 
AtCoder Regular Contest 048
AtCoder Regular Contest 048AtCoder Regular Contest 048
AtCoder Regular Contest 048
AtCoder Inc.
 
MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説
AtCoder Inc.
 
AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説
AtCoder Inc.
 
DDPC 2016 予選 解説
DDPC 2016 予選 解説DDPC 2016 予選 解説
DDPC 2016 予選 解説
AtCoder Inc.
 
arc047
arc047arc047
arc047
AtCoder Inc.
 
abc032
abc032abc032
abc032
AtCoder Inc.
 
CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説
AtCoder Inc.
 
AtCoder Regular Contest 046
AtCoder Regular Contest 046AtCoder Regular Contest 046
AtCoder Regular Contest 046
AtCoder Inc.
 
abc031
abc031abc031
abc031
AtCoder Inc.
 
CODE FESTIVAL 2015 解説
CODE FESTIVAL 2015 解説CODE FESTIVAL 2015 解説
CODE FESTIVAL 2015 解説
AtCoder Inc.
 
CODE FESTIVAL 2015 予選B 解説
CODE FESTIVAL 2015 予選B 解説CODE FESTIVAL 2015 予選B 解説
CODE FESTIVAL 2015 予選B 解説
AtCoder Inc.
 
AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説
AtCoder Inc.
 
AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説
AtCoder Inc.
 
CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説
AtCoder Inc.
 
AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説
AtCoder Inc.
 
AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説
AtCoder Inc.
 
AtCoder Beginner Contest 028 解説
AtCoder Beginner Contest 028 解説AtCoder Beginner Contest 028 解説
AtCoder Beginner Contest 028 解説
AtCoder Inc.
 

More from AtCoder Inc. (20)

Square869120 contest #2
Square869120 contest #2Square869120 contest #2
Square869120 contest #2
 
Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説
Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説
Disco Presents ディスカバリーチャンネルプログラミングコンテスト2016 本選 解説
 
Chokudai Contest 001
Chokudai Contest 001Chokudai Contest 001
Chokudai Contest 001
 
AtCoder Regular Contest 048
AtCoder Regular Contest 048AtCoder Regular Contest 048
AtCoder Regular Contest 048
 
MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説
 
AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説
 
DDPC 2016 予選 解説
DDPC 2016 予選 解説DDPC 2016 予選 解説
DDPC 2016 予選 解説
 
arc047
arc047arc047
arc047
 
abc032
abc032abc032
abc032
 
CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説CODE FESTIVAL 2015 沖縄ツアー 解説
CODE FESTIVAL 2015 沖縄ツアー 解説
 
AtCoder Regular Contest 046
AtCoder Regular Contest 046AtCoder Regular Contest 046
AtCoder Regular Contest 046
 
abc031
abc031abc031
abc031
 
CODE FESTIVAL 2015 解説
CODE FESTIVAL 2015 解説CODE FESTIVAL 2015 解説
CODE FESTIVAL 2015 解説
 
CODE FESTIVAL 2015 予選B 解説
CODE FESTIVAL 2015 予選B 解説CODE FESTIVAL 2015 予選B 解説
CODE FESTIVAL 2015 予選B 解説
 
AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説
 
AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説
 
CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説
 
AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説
 
AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説
 
AtCoder Beginner Contest 028 解説
AtCoder Beginner Contest 028 解説AtCoder Beginner Contest 028 解説
AtCoder Beginner Contest 028 解説
 

Union find(素集合データ構造)