暴力算法: 1,判断两个元素是否在一个集合内 arr[x]=x;if(arr[x]==arr[y])cout<<"YES"; 时间复杂度O(1);
2,集合合并:(实现性复杂)
暴力算法实现困难——————>如何优化?——————>并查集优化
并查集: 1,合并两个集合; 2,判断两个元素是否在一个集合内。
并查集基本原理:用一棵树来维护同一个集合。
①.区间合并。
如图所示:假设有四个集合,分别为{1},{2},{3},{4},用树来表示即为四个根节点。
我们给每个元素都存入数组,元素值作为下标,下标所代表的数组值等于该值的祖宗,即根节点的值,并且根节点的值就为下标:arr[x]=x---->根节点表示方法,arr[y]==x---->非根节点表示方法。
举个例子,我们将上图中2,3,4,分别合并到集合1中。
②.判断两个元素是否为同一个集合。
判断两个元素的根节点的x值是否相等即可。
例题:
#include <iostream>
#include <algorithm>
using namespace std;
const int N=100010;
int arr[N];
int m,n;
int find(int x)
{
if(x!=arr[x])arr[x]=find(arr[x]);
return arr[x];
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)arr[i]=i;
while(m--)
{
string s;
cin>>s;
int a,b;
cin>>a>>b;
if(s=="M")arr[find(a)]=find(b);
else
{
if(find(a)==find(b))cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}