首页 > 其他分享 >23-4-15--并查集--部落

23-4-15--并查集--部落

时间:2023-04-15 23:23:08浏览次数:36  
标签:pre fx 15 -- ll 查集 int 小圈子 find

在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。

输入格式:

输入在第一行给出一个正整数N(≤104),是已知小圈子的个数。随后N行,每行按下列格式给出一个小圈子里的人:

K P[1] P[2] ⋯ P[K]

其中K是小圈子里的人数,P[i](i=1,⋯,K)是小圈子里每个人的编号。这里所有人的编号从1开始连续编号,最大编号不会超过104。

之后一行给出一个非负整数Q(≤104),是查询次数。随后Q行,每行给出一对被查询的人的编号。

输出格式:

首先在一行中输出这个社区的总人数、以及互不相交的部落的个数。随后对每一次查询,如果他们属于同一个部落,则在一行中输出Y,否则输出N

输入样例:

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

输出样例:

10 2
Y
N

思路:

典型的并查集问题,先用pre[i]=x的形式,表示i的父节点为x;

之后两个函数,find(x)函数用来寻找x的祖先,join(x,y)函数用来把x和y的祖先设为共同的一个

int pre[10005];


int find(int x)
{
        //如果x的父节点是他自己,那么他就是祖先
    if(x==pre[x])
        return x;

        //用来压缩路径,减少递归次数
    return pre[x]=find(pre[x]);
}
void join(int x,int y)
{
        //如果二者的祖先不相等,将其中一个的祖先的父节点设为另一个的祖先
    int fx=find(x),fy=find(y);
    if(fx!=fy)
    {
        pre[fy]=fx;
    }
    
}    

之后再来看这道题,不停地join()就行。值得一提的小技巧是,对于每一个小圈子来说,取第一个编号来代表这个小圈子,整个小圈子的默认父节点都是它,存在一个数组里,最后遍历这个数组来统计人数以及部落个数。

代码如下:

#include <iostream>
#include <unordered_set>
using namespace std;

typedef long long ll;

ll pre[10005];
ll find(ll x)
{
    if(x==pre[x])
        return x;
    return pre[x]=find(pre[x]);
}
void join(ll x,ll y)
{
    ll fx=find(x),fy=find(y);
    if(fx!=fy)
    {
        pre[fy]=fx;
    }
    
}
ll book[10005],cnt;
int main()
{
    unordered_set<ll> population,tribes;
    for(ll i=0;i<10005;i++)
    {
        pre[i]=i;
    }
    ll n;
    cin>>n;
    ll head[10005]={0};
    for(ll x=0;x<n;x++)
    {
        
        ll k;
        scanf("%lld",&k);
        ll p[10005]={0};
        for(ll i=0;i<k;i++)
        {
            
            scanf("%lld",&p[i]);
            population.insert(p[i]);
            join(p[0],p[i]);
        }
        head[x]=p[0];
    }
    for(ll i=0;i<n;i++)
    {
        tribes.insert(find(head[i]));
    }
    printf("%d %d\n",population.size(),tribes.size());
    ll q;
    cin>>q;
    while(q--)
    {
        ll a,b;
        scanf("%lld %lld",&a,&b);
        if(find(a)==find(b))
        {
            cout<<"Y"<<endl;
            
        }else{
            cout<<"N"<<endl;
        }
    }
    
}

 结果:

 

标签:pre,fx,15,--,ll,查集,int,小圈子,find
From: https://www.cnblogs.com/daniel350-wang/p/17322250.html

相关文章

  • Linux-定期执行程序_crond与crontab
    1、Crond简介:  (1)概念:    Crond是linux系统中用来定期执行命令/脚本或指定程序任务的一种服务或软件。  (2)命令:status//查看此服务的运行状态stop//停止此服务restart//重启此服务reload//重新载入配置/sbin/servicecrondstart......
  • 在Excel中输入特殊字符   
    使用标准的计算机键盘你可以输入大约94种不同的字符,包括字母、数字和其它一些功能符号。但是我们在实际应用中会使用很多其它的字符,这些字符都不能通过标准的US键盘直接输入,例如标准字体Arial中就有大约200种不同的字符可以使用,包括英镑符号£,欧元符号€,版权符号©等。本文描述了......
  • pdo 插入记录用?做占位符
    <?phpheader("Content-type:text/html;charset=utf-8");//设置中国时区date_default_timezone_set('PRC');$dsn="mysql:host=127.0.0.1;port=3306;dbname=test;charset=utf8";$username="root";$password="root";......
  • go test main包报错
    前言先提出问题,再说明原因.有如下一段代码:当执行gotest测试时,会报如下错误:main.test/var/folders/55/47pl3jxx6rg7m0r6xvn4f7wr0000gn/T/go-build2769402238/b001/_testmain.go:13:8:couldnotimportmain(cannotimport"main")FAILmain[buildfailed]......
  • 如果 Git 远程库与本地库不一致,导致无法将本地代码推送到远程库中,
    如果Git远程库与本地库不一致,导致无法将本地代码推送到远程库中,可以按照以下步骤操作:首先,使用gitfetch命令将远程库中的代码更新到本地仓库中,但不会合并到当前分支中。可以使用以下命令:gitfetchorigin这个命令会将远程库中的代码更新到本地仓库中的origin分支中。......
  • VS版本对应关系
    VS全名是MicrosoftVisual Studio,是很⼤的⼀个开发环境,包含很多⾼级语⾔的开发环境,VC只是VS其中的⼀个开发环境。Visual Studio 6 : vc6Visual Studio 2003 : vc7Visual Studio 2005 : vc8Visual Studio 2008 : vc9Visual Studio 2010 : vc10Visua......
  • 使用ThreadLocal请务必remove
    原文地址:https://www.cnblogs.com/panchanggui/p/15105419.html特别注意,web容器的线程是重复使用的,web容器使用了线程池,当一个请求使用完某个线程,该线程会放回线程池被其它请求使用,这就导致一个问题,不同的请求还是有可能会使用到同一个线程(只要请求数量大于线程数量),而ThreadLocal......
  • 深度学习Pytorch中组卷积的参数存储方式与剪枝的问题
    写这个主要是因为去年做项目的时候需要对网络进行剪枝普通卷积倒没问题涉及到组卷积通道的裁剪就对应不上当时没时间钻研现在再看pytorch钻研了一下仔细研究了一下卷积的weight.data的存储1.搭建网络这里先随便搭建一下网络放几个深度可分离卷积和普通卷积import......
  • this与super
         对象实例化时,至少有一条从本类出发抵达Object的通路,而打通这条路的两个主要工兵就是this和super,逢山开路,遇水搭桥。但是this和super往往是默认无闻的,在很多情况下可以省略,比如: · 本类方法调用本类属性 · 本类方法调用另一个本类属性 · 子类构造方法......
  • 信息论之从熵、惊奇到交叉熵、KL散度和互信息
    一、熵(PRML)考虑将A地观测的一个随机变量x,编码后传输到B地。这个随机变量有8种可能的状态,每个状态都是等可能的。为了把x的值传给接收者,需要传输⼀个3⽐特的消息。注意,这个变量的熵由下式给出:⾮均匀分布⽐均匀分布的熵要⼩。如果概率分布非均匀,同样使用等长编码,那么并不是最......