并合集
題目描述
一共有n個數,編號是1~n,最開始每個數各自在一個集合中,
現在要進行m個操作,操作共有兩種:
“M a b”,將編號為a和b的兩個數所在的集合合并,如果兩個數已經在同一個集合中,則忽略這個操作;
“Q a b”,詢問編號為a和b的兩個數是否在同一個集合中;
#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的祖先根節點
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/266981.html
標籤:其他
上一篇:【游戲開發崗面經總結5】(面相物件和面相程序的區別,多型,CG,設計模式,行程執行緒協程,記憶體區域存放,協程的原理)
