アルゴリズムテンプレート:ユニオンコレクション

ユニオンコレクション

タイトル説明
1からnまでの合計n個の番号があり、各番号は最初にセットになっています。
今実行されるm個の操作があると、2つの操作がある:
「M AB」、マージ二つの数が同じ集合に既にある場合、この操作は無視配置された2つの番号は番号とBセットは、
" Q ab "、aとbの番号が付けられた2つの番号が同じセットにあるかどうかを尋ねます。

#include<iostream>

using namespace std;
const int N = 1e6 + 10;
int p[N];

```cpp
int find(int x)
{
    
    
    if(p[x] != x)p[x] = find(p[x]);
    return p[x];
}

int main(void)
{ int n、m; cin >> n >> m; for(int i = 1; i <= n; i ++)p [i] = i;


while(m--)
{
    char op[2];
    int a, b;
    scanf("%s%d%d" ,op,&a,&b);
    if(op[0] == 'M')
    {
        p[find(a)] =find(b);
    }
    else if(op[0] == 'Q')
    {
        if(find(a) == find(b))puts("Yes");
        else puts("No");
    }
}

}

**并合集**
一种快速对字符串以及二进制数组元素的管理方式,用树的形式进行存储;
**代码分析**
对于1~n这些数字,我们创建了一个数组p来记录他的祖先节点,运用下标与实际数字进行关联,例如p[i]记录的就是i的祖先节点,在程序一开始的时候,我们将每个节点的祖先设置为他自己,然后通过合并数组的操作实现树的建立;
*集合的合并*
树的根节点存储集合的信息,p数组的单元存储节点的祖先,将根节点的祖先修改为另一个集合就完成了就和的合并;

```cpp
int find(int x)
{
    if(p[x] != x)p[x] = find(p[x]);
    return p[x];
}

この操作により、xの祖先ルートノードの検索が完了します。

おすすめ

転載: blog.csdn.net/ZMTH010123/article/details/114439563