并查集 亲戚

题目描述

或许你并不知道,你的某个朋友是你的亲戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孙子。如果能得到完整的家谱,判断两个人是否亲戚应该是可行的,但如果两个人的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系实非人力所能及。在这种情况下,最好的帮手就是计算机。为了将问题简化,你将得到一些亲戚关系的信息,如Marry和Tom是亲戚,Tom和Ben是亲戚,等等。从这些信息中,你可以推出Marry和Ben是亲戚。请写一个程序,对于我们的关于亲戚关系的提问,以最快的速度给出答案。

输入

输入由两部分组成。 第一部分以N,M开始。N为问题涉及的人的个数,M表示已经知道M对亲戚关1<=N,M<=100000,接下来M行,每行有两个数ai, bi,表示已知ai和bi是亲戚。这些人的编号为1,2,3,…, N。接下来输入一个整数P(1<=P<=100000),表示有P次询问,接下来P行,每行为ci, di,表示询问ci和di是否为亲戚。

输出

若ci和di为亲戚,则输出“Yes”,否则输出“No”。

样例输入

10 7 2 4 5 7 1 3 8 9 1 2 5 6 2 3 3 3 4 7 10 8 9

样例输出

Yes No Yes

#include<iostream>

int f[100000];

using namespace std;

int find(int x)

{

    if(f[x]==x)

    return x;

    else

    return f[x]=find(f[x]);

}

void merge(int a,int b)

{

     f[find(a)]=find(b);

}

int main()

{

    int n,m;

    cin>>n>>m;

   

    int i,a,b;

    for(i=1;i<n+1;i++){

      f[i]=i;}

    for(i=0;i<m;i++){

      scanf("%d%d",&a,&b);

      merge(a,b);}

    int p;

    cin>>p;

    for(i=0;i<p;i++){

      scanf("%d%d",&a,&b);

      if(find(a)==find(b))

        printf("Yes\n");

      else

      {printf("No\n");}    

    }

    //system("pause");

    return 0;

}

时间: 2024-08-10 17:21:17

并查集 亲戚的相关文章

并查集——亲戚(洛谷1551)(可做并查集模板)

题目背景 Background 若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系. 题目描述 Description 规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚.如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚. 输入输出格式 Input/output 输入格式: 第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关

洛谷P1551亲戚 并查集

洛谷P1551亲戚   并查集  按秩合并 + 路径压缩 #include <bits/stdc++.h> using namespace std ; const int N = 5011 ; int fa[N],rk[N] ; int n,m,Q ; inline void init() { for(int i=1;i<=n;i++) fa[ i ] = i,rk[ i ] = 1 ; } inline int find(int x) { if(x==fa[ x ]) return x

【codevs1073/P1551】家族/亲戚——并查集

题目链接:codevs,洛谷 这道题就是并查集的基础题,getf函数寻找该节点的祖先,要注意在查找的时候可以顺便把路上的节点的父节点也改为当前祖先(即路径压缩). 询问的时候不能因为两个点的父节点不同就说他们不是同一棵树上的,要一直找到他们的祖先再做比较. 具体实现细节看代码: #include<cstdio> #include<cstring> using namespace std; int f[5005]; int read() { int ans=0,f=1;char c=

并查集 (Union-Find Sets)及其应用

定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并. 主要操作 初始化 把每个点所在集合初始化为其自身. 通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式,时间复杂度均为O(N). 查找 查找元素所在的集合,即根节点. 合并 将两个元素所在的集合合并为一个集合. 通常来说,合并之前,应先判断两个元素是否属于

并查集/生成树问题 | 问题集合

写在前面 似乎没什么可以写的? 那还是扯一下吧. 题目大部分带题号没给特殊地址/链接的都是洛谷的题 然后亲戚和朋友两道题库被我刷烂的题我就不搬进来了(:懒 P1536 村村通 题目描述 某市调查城镇交通状况,得到现有城镇道路统计表.表中列出了每条道路直接连通的城镇.市政府"村村通工程"的目标是使全市任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要相互之间可达即可).请你计算出最少还需要建设多少条道路? 输入格式: 每个输入文件包含若干组测试测试数据,每组测试数据的第一行给出

并查集—分离集合森林实现

并查集总结 今天总结一下并查集,这个完了之后,寒假学的数据结构基础的模板类的题目差不多就完了,对于模板题,敲上10遍.20遍.30遍,那么模板就不是模板,就成为了你自己的东西,就好像 A+B 一辈子也忘不了,以后每天敲一遍模板题,加深对模板的理解. 并查集,一般使用的是 数组实现.树实现,其中数组实现时间复杂度较高,树实现也就是分离集合森林 查找.合并的时间复杂度不会 超过 O(log2n) n个人,m对有亲戚关系的 10 7 1 2 2 3 2 4 3 4 5 6 6 7 8 9 初始化:{1

并查集小记

并查集: 并查集,一种树型的数据结构,处理一些不相交集合的合并及查询问题.比如问题:某个家族人员过于庞大,要判断两个人是否是亲戚,不太容易.现给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系. 规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚.如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚. 从基本实现集合的结构出发: 1.单纯的快速查找: 若id相同则在一个集合中,下图中,( 2, 3, 4, 9 )为一集合, 3 和 6 不在一个集合中 合并集合时,需逐个比较将

并查集(初步)

并查集可以查询某个是否在一个集合里,而且可以把两个或以上的集合合并起来. 比如有三个集合{1, 3, 5, 7, 9}, {2, 4, 6, 8, 10}, {11, 12, 13, 14},其中1和5在一个集合里2和11不在一个集合里. 经典的题目:n个人,有m对关系,如果a和b是亲戚,b和c是亲戚,则a和c也是亲戚,求有多少组亲戚.描述的不是很好,看例子吧.假设有5个人,1和2是亲戚,2和3是亲戚,4和5是亲戚.那么答案是2,因为亲戚组有两组,分别是{1, 2, 3},{4, 5}. 树关系

about_并查集

前天刚学了并查集,挺好用的,虽然我现在只会用它来解决是不是亲戚啊,是不是朋友啊,带权并查集还不是很理解. 并查集也叫做不相交集合,主要有3个操作,初始化,查找,合并. 并查集其中一个很大的应用就是kruskal嘛. 并查集就是说,有n个元素嘛,我们把每个元素初始化为一个集合,然后不断查找,看看是不是有关系,有的话就合并. 代码手打,无语法高亮,其实是我不知道怎么弄,囧. const int MAXN=1000+10;//最大点数 int father[MAXN]; int rank[MAXN];