当前位置:首页 > 题解目录 > 正文内容

【题解】亲戚

亿万年的星光3年前 (2023-03-30)题解目录3748


【题目描述】

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

规定: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个询问的答案为“具有”或“不具有”亲戚关系

【样例输入】

6 5 3
1 2
1 5
3 4
5 2
1 3
1 4
2 3
5 6

【样例输出】

Yes
Yes
No

【题目分析】

并查集的模板题

【参考代码】

#include<bits/stdc++.h>
using namespace std;
int n,m,q,f[10010],x,y,a,b;
int find(int x)//找出某棵树的老大 
{
	if(f[x]==x)//x是x的老大,
		return x;
	else 
		return  f[x]=find(f[x]);//x不是他自己的老大,所以他上面还有老大,递归 
}
void merge(int x,int y)
{
	//先找到两个元素对应的根对应的元素 
	int fx = find(x); 
	int fy = find(y);
	if(fx==fy) return;
	else f[fy]=fx;  //否则令元素 x的根指向元素 y的根  
	return ;
}
int main()
{
	cin>>n>>m>>q; 
	//初始化每个人 
	for(int i=1;i<=n;i++)
		f[i]=i;
	//合并	
	for(int i=1;i<=m;i++)
	{
	     cin>>x>>y; 
	     merge(x,y);
	}
	//询问 
	for(int i=1;i<=q;i++)
	{
		cin>>a>>b; 
		if(find(a)==find(b)){
			//如果a所在子集的老大和b所在子集的老大一样,
			//那么可以判断出知a和b属于同一个集合
			cout<<"Yes"<<endl;
		}
		else{
			cout<<"No"<<endl; 
		}	
	}
	return 0;
}


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

标签: 并查集
分享给朋友:

相关文章

【题解】前缀最小值

【题目描述】求一个数列的所有前缀最小值之和。即:给出长度为n的数列a[i],求出对于所有1<=i<=n,min(a[1],a[2],...,a[i])的和。由于读入较大,数列由随机种子生成...

【题解】均分蛋糕

【题解】均分蛋糕

【题目描述】小明的生日要到了!根据习俗,他需要将一些派分给大家。他有 N 个不同口味、不同大小的派。有 F 个朋友会来参加我的派对,每个人会拿到一块派(必须一个...

【题解】踩方格

【题目描述】有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:a、每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;b、走过的格子立即塌陷无法再走第二次;c、只能向北、东、西三个方向走;请问...

【题解】最大子矩阵

【题目描述】已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 × 1)子矩阵。比如,如下4 × 4的矩阵0  -2 -7&nb...

【题解】合根植物

【题解】合根植物

【题目描述】w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成...

【题解】跳格子2

【题目描述】地面上有一排长度为n的格子1-n,每个格子上都有一个数xi,开始时你在位置0,每次你可以向前跳1-2格,然后取走格子上的数,直到跳到位置n+1。取走的数的和就是你的得分,现在你想知道你可能...