因为出去玩的原因好久没有更新了,今天做了一个关于查并集的题
题目:
题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 N,M ,表示共有 N 个元素和 M 个操作。
接下来 MM 行,每行包含三个整数z,x,y;
当z=1时,将x,y合并
当z=2时,判断x和y是不是在一个集合,是输出Y,反之,N;
输出格式
对于每一个 z =2 的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N 。
思路:
这个题就是完全的对于查并集的一个应用没有任何的变化。但是在做这个题中也出现了一个问题,那就是两个根结点合并的时候,根结点下面的子节点的数值不会因为之前根结点的发生变化而改变了子节点的数值。换句话说,就是根结点变化之后,子结点的数值是之前根结点的,没有更新,这种情况就再用一个查找函数,使得子结点的根结点得到更新。
代码:
#include <iostream>
using namespace std;
const int maxn=1000000;
int s[maxn+1];
void inti()
{
for(int i=1;i<=maxn;i++)
s[i]=i;
}
//查找函数的一种形式
//int find_s(int n)
//{
// if(n!=s[n])
// {
// s[n]=find_s(s[n]);
//
// }
// return s[n];
//
//}
//查找函数的另一种形式
int find_s(int a)
{
if(s[a]==a) return a;
return s[a]=find_s(s[a]);
}
void union_s(int a,int b)
{
a=find_s(a);
b=find_s(b);
if(a!=b)s[b]=s[a];
}
int main()
{
int n,m;
cin>>n>>m;
inti();
int z,w,q;
while(m--)
{
cin>>z>>w>>q;
if(z==1)
union_s(w,q);
else
{
if(find_s(w)==find_s(q))
cout<<"Y"<<endl;
else
cout<<"N"<<endl;
}
}
//for(int i=1;i<=n;i++)
// cout<<s[i]<<" ";
}