突然照合ない思い出したときに、これは非常に基本的な内容で、クラスカルは前に書かれました。
実際には、ボードには、保存したいです
素集合データ構造は、(互いに素なセットのみ)のコレクションを処理するため、木です。
物事の束について「感覚的な理解は、」いくつかの山、それぞれ中で唯一の山のすべてに分割します。
父の具体的な実現は、その要素の親ノードを指し、配列を使用します。すべての要素が、自身のある初期の父親は、自分のコレクション内の各要素を表しています。同じのための2つの同じセット内の要素、および彼らの祖先の場合。
2つの主要な機能:参加して見つけます。
私が見つけることについてお話しましょう:
int型(見つけるint型のx){ 場合(!父[X] = x)の父を[X] = (父[x)を検索。 返す父を[X]; }
ウェルxは父親である場合、それはルート自身のコレクションである、またはルートノード( - 収集ポイントがルートノードの下に直接接続されている方法パス圧縮)まで、層ごとに問い合わせて、理解されます。この機能は、主に使用され、二つの要素によって同一の祖先であり、同じセット内の2つの要素かどうかが決定されます。
その後、参加します:
ボイド(参加INT X、int型の{Y) int型の FX =検索(X)、FY =は(Y)に参加。 もし(!FX = FY)父[FY] = FX。 返します。 }
2つの偉大なコレクションを組み合わせ置けば、それは、想像する必要があり、ルートノードに直接最も簡単な操作で収集し、次に別のコレクションです。(構造に関しては......非常に紛らわしいものになる次回を検索して、行に仕上げます)
コードの実装:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 int型の父[ 10010 ]; int型の検索(int型x)は{ 場合(父[X] = X!)父[X] = 検索(父[X]); 返す父を[X]; } ボイドは、(参加int型のx、int型のY){ int型(X)、FY =を探す= FXを(Y)に参加します。 もし(!FX = FY)父[FY] = FX。 返します。 } int型のmain(){ ため(int型のI = 1 ; I <= 10000; i)は父++を[I] = I; INTのN、M、X、Y。 scanf関数(" %d個の%のD "、&N、&M)。 一方、(M-- ){ scanf関数(" %D%dの"、およびX&Y)。 (x、y)が参加。 } int型のP。 scanf関数(" %のD "、&P)。 一方、(P-- ){ scanf関数(" %d個の%のD "、およびX&Y)。 もし(検索(X)=(y)を見つけて下さい!)のprintf(" F \ nを" ); printf(" Tを\ n " ); } 戻り 0 。 }