はい、2つのノードが同じルートを持っているかどうかをテストするだけです。グラフを作成するときにパス圧縮を使用すると、これは非常に高速であることがわかります。
クラスカルのアルゴリズムの実装に取り入れようとしているからだと思います。接続されているすべてのコンポーネントを見つけたら、各互いに素なセットからの各素集合を示す出力を並べ替えたいと思います。ご迷惑をおかけして申し訳ありませんが、可能であれば、意味を説明するための疑似コードがありますか?
セットは、共通のルートノードによってすでに識別されています。 すべてのユニオンを実行すると、それぞれの一意のセットに単一のルートが作成されます。したがって、各ノードを実行して呼び出しますFind
。これはどう:
typedef std::list< Node* > TNodeList;
typedef std::map< Node*, TNodeList > TSetMap;
TSetMap mysets;
// Assuming you have nodes stored in the list type I declared above...
for( TNodeList::iterator n = nodes.begin(); n != nodes.end(); n++ )
{
Node *thisnode = *n;
Node *rootnode = Find(thisnode);
// Add to list for root. Using the [] operator on map will create a new
// list if none exists for that node.
mysets[rootnode].push_back(thisnode);
}
これで、すべてのセットを個別のリストとして含むマップが作成され、好きなことを実行できます...
std::cout << "Number of disjoint sets: " << mysets.size() << std::endl;
int count = 0;
for( TSetMap::iterator s = mysets.begin(); s != mysets.end(); s++ )
{
TNodeList & nl = s->second;
std::cout << "Set " << ++count << " contains " << nl.size() << " nodes\n";
}
これらすべての呼び出しをFind
効率的に行うには、関数にパス圧縮を実装する必要がありますUnion
。