题目背景
若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。

题目描述
规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

输入输出格式
输入格式:
第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。

以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Mi和Mj具有亲戚关系。

接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。

输出格式:
P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”或“不具有”亲戚关系。

输入输出样例
输入样例#1:
6 5 3
1 2
1 5
3 4
5 2
1 3
1 4
2 3
5 6
输出样例#1:
Yes
Yes
No

今天get新技能并查集,这题比较简单,就是一个简单的裸并查集,直接上代码了;

#include<iostream>
#define maxsize 5000
using namespace std;
int a[maxsize][maxsize];
int b[maxsize][maxsize];
typedef struct node
{
	int data;
	int rank;
	int parent;
}UFSTREE;
void def(UFSTREE ufs[],int n){
	for(int i=1;i<=n;i++){//初始化 
		ufs[i].data=i;
		ufs[i].rank=0;
		ufs[i].parent=i;//将每个节点自己作为自己的根节点 
	}
}
int find_x(UFSTREE ufs[],int x){
	if(x!=ufs[x].parent)
	return  find_x(ufs,ufs[x].parent);//递归寻找根节点 
	else
	return x;
}
void union_s(UFSTREE ufs[],int x,int y){
	int a=find_x(ufs,x);//找x的根节点 
	int b=find_x(ufs,y);//找y的根节点 
	if(ufs[a].rank>ufs[b].rank){//确定深度高的树作为合并后的根节点 
		ufs[b].parent=a;
	}else{
		ufs[a].parent=b;
		if(ufs[a].rank==ufs[b].rank){//如果深度相同,合并后,深度需要+1 
			ufs[b].rank++;
		}
	}
}
int main()
{
	UFSTREE ufs[maxsize];
	int n,m,p;
	cin>>n>>m>>p;
	for(int i=0;i<m;i++){//二维数组存储关系 
		cin>>a[i][0]>>a[i][1];
	}
	for(int i=0;i<p;i++){//二维数组存储需要检验的关系 
		cin>>b[i][0]>>b[i][1];
	}
	def(ufs,n);//初始化 
	for(int i=0;i<m;i++){
		union_s(ufs,a[i][0],a[i][1]);//合并关系 
	}
	for(int i=0;i<p;i++){
		if(find_x(ufs,b[i][0])==find_x(ufs,b[i][1]))//确认关系 
		cout<<"Yes"<<endl;
		else
		cout<<"No"<<endl;
	}
}