并查集

本文深入探讨了并查集的基本概念及其在解决实际问题中的应用,以家族亲戚关系图为例,详细阐述了并查集的查找与合并操作,并通过具体代码实现解决了亲戚关系判断问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

所谓并查集,就是将一些有关系的东西合并起来,用于方便查找。
在此我也不讲太多理论的东西(理论参看高级数据结构.pdf中并查集部分),还是讲讲实际应用吧。 
顾名思义,并查集就是并着查的集合。对他的操作有两种: 
查找操作:(查找某个元素所在的集合):
查找操作
要表示一个集合,就要加上一个标记,那些用什么来标记呢,就用他的第一个元素。
合并操作:(将两个集合合并):
将所要和并的两个元素所在集合的标记节点合并。

接下来我们来看几道例题:
   家    族
描述 Description 
若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

输入格式 Input Format
第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Ai和Bi具有亲戚关系。接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。
输出格式 Output Format
P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”或“不具有”亲戚关系。


该题是标准并查集经典题目,只要找标记就行了。
程序如下:
读入数据,将节点的标记记为他自己:

#include<iostream>
using namespace std;
int a[5000];
int i,j,k,m,n,p;
void Init()
{
    for(int i=1;i<=n;i++) 
        a[i]=i;
}
int fun(int x)
{
    if(a[x]!=x)
    {
        a[x]=fun(a[x]);
        return a[x];
    }
    else return x;
}
int main()
{
    cin>>n>>m>>p;
    Init();
    for(int i=1;i<=m;i++)
    {
        cin>>j>>k;
        if(fun(j)!=fun(k)) a[fun(k)]=j;
    }
    for(int i=1;i<=p;i++)
    {
        cin>>j>>k;
        if(fun(j)==fun(k)) cout<<"YES\n";
        else cout<<"NO\n";
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值