种类并查集+入门题A Bug's Life

2023-11-08

我觉得种类并查集还是先从一个基础入门题讲起吧。

Background
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs.
Problem
Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.

Input

The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.

Output

The output for every scenario is a line containing "Scenario #i:", where i is the number of the scenario starting at 1, followed by one line saying either "No suspicious bugs found!" if the experiment is consistent with his assumption about the bugs' sexual behavior, or "Suspicious bugs found!" if Professor Hopper's assumption is definitely wrong.

Sample Input

2
3 3
1 2
2 3
1 3
4 2
1 2
3 4

Sample Output

Scenario #1:
Suspicious bugs found!

Scenario #2:
No suspicious bugs found!

Hint

Huge input,scanf is recommended.

 

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <cstdio>
#include <stack>
#include <set>
#define MAXN 2004
using namespace std;

int f[MAXN],r[MAXN];
bool flag;

int getf(int x){
    if(x == f[x]) return x;
    int t = getf(f[x]);
    r[x] = (r[x] + r[f[x]]) % 2;
    f[x] = t;
    return t;
}

void Union(int a,int b){
    int fa = getf(a);
    int fb = getf(b);
    if(fa == fb){
        if(r[a] == r[b]){
            flag = false;
        }
        return;
    }
    f[fb] = fa;
    r[fb] = (r[a]+1-r[b]+2)%2;
}

int main(){
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;++i){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){
            f[i] = i;
            r[i] = 0;
        }
        flag = true;
        int a,b;
        for(int i=0;i<m;++i){
            scanf("%d%d",&a,&b);
            if(flag) Union(a,b);
        }
        printf("Scenario #%d:\n",i);
        if(flag) cout << "No suspicious bugs found!" << endl;
        else cout << "Suspicious bugs found!" << endl;
        cout << endl;
    }
    return 0;
}

其实乍一看,种类并查集和基础并查集大致一样,无非就是多了两句代码:getf函数中的 r[x] = (r[x] + r[f[x]]) % 2 和 Union函数中的 r[fb] = (r[a]+1-r[b]+2)%2,不用多想,这两句就是种类并查集的关键,所以在这里就重点解释这两句的意思。

首先,就这道题而言,很明显昆虫之间就两种关系,同性和异性,我们分别标记为0 和 1,用 r 数组存放,具体点说就是 r[i] == 0 表示 i 跟 f[i] 是同性,反之异性。

首先我们定义一种关系:f[a] -> a 代表 r[a] ,记准这个,在以后的推理中很有帮助。

在getf函数中,我们假设最终的根节点为root(定义为root只是为了帮助理解,这里不用多想,往下看就行了),然后在压缩路径的同时,首先看到关键代码:r[x] = (r[x] + r[f[x]]) % 2,这一句其实是实时更新 r[x], 因为我们知道,在压缩路径的同时,x的直接父节点f[x]可能就会变了(变的话就是变为root),所以r[x]也可能随之改变,怎么变呢?是不是可以这样表示:root->x = root->f[x] + f[x]->x。有可能你会问,root也不一定是f[x]的直接父节点啊,记住,因为路径压缩是递归的,所以在此之前,root已经是f[x]的直接父节点了,所以root->f[x] 这一句是没毛病的。根据我们之前的关系将这句翻译过来不就是r[x] = (r[x] + r[f[x]]) % 2,至于为什么%2,是因为在这个题中我们只定义了0,1两种关系,正确性可以自己验证。

在Union函数中涉及了两种情况:fa == fb,即a,b根节点相同,属于同一棵树,只判断a和b跟根节点的关系是否相同就行了,即r[a] == r[b]。

fa != fb时,分属两棵树,需要将它们联系在一起,做法就是将一个根节点挂在另一个根节点上,即f[fb] = fa,同时更新 r数组的关系,怎么更新?我们的做法是将fb挂在fa上,根据我们定义的关系,可以这样表示 fa->fb = fa->a + a->b + b->fb,翻译过来就是r[fb] = (r[a] + 1 - r[b] + 2) %2,其中 + 1是题目暂时给出的关系,为异性,+2是避免负数。

大致就是这么个意思吧。我觉得之前说的要记准的那个关系我觉得挺好用的,推理很方便,还有要记得活用,这个就废话了,还是要多多练习。

POJ 1703

POJ 1182 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

种类并查集+入门题A Bug's Life 的相关文章

  • 卷积神经网络详解

    卷积神经网络 Convolutional Neural Networks CNN 是应用最多 研究最广的一种神经网络 卷积神经网络 以下简称CNN 主要用于图片分类 自动标注以及产品推荐系统中 以CNN实现图片分类为例 图像经过多个卷积层

随机推荐

  • 【Unity入门计划】CreatorKitFPS:第一人称射击3D小游戏

    目录 Unity学习教程 1 添加并载入项目资源 添加项目资源 载入到Unity 2 载入Scene 3 从预制体添加射击Targets 4 管理游戏对象 4 1创建分组关系 4 2 区分相对坐标 世界坐标 5 自己做一个预制件 5 1 添
  • 【Python全栈开发从入门到实战】持续更新中......

    本专栏为Python全栈开发系列文章 技术包括Python基础 函数 文件 面向对象 网络编程 并发编程 MySQL数据库 HTML JavaScript CSS JQuery bootstrap WSGI Django Flask 后期运
  • OpenCV中的图像变换——傅里叶变换

    OpenCV中的图像变换 傅里叶变换 1 效果图 2 原理 3 源码 3 1 Numpy实现傅里叶变换 3 2 OpenCV实现傅里叶变换 3 3 HPF or LPF 参考 这篇博客将介绍OpenCV中的图像变换 包括用Numpy Ope
  • post方式加载iframe

    我们平常使用iframe时 直接设定src属性只能是get请求方式 get请求的参数大小有限制 如何实现即使用iframe又能通过post请求 两种方式 ajax使用post请求返回页面 直接将返回的页面数据放入iframe标签中 结合fo
  • linux-内核锁

    目录 一 铺垫知识 1 指令执行流 2 上下文 3 抢占 二 内核锁基础知识 1 为什么要用锁 why 2 锁保护什么 what 3 锁是如何保护资源的 How 三 各类锁的介绍 1 原子操作 2 spinlock 3 mutex 4 进程
  • HBase学习 -安装Hbase(2)

    目录 安装模式 独立式HBase安装 使用自带的Zookeeper 独立于HDFS的HBase安装 使用自带的Zookeeper 伪分布式HBase安装 使用自带的Zookeeper 伪分布式HBase安装 不使用自带的Zookeeper
  • nestjs: Redundant character escape ‘\@‘ in RegExp 处理

    问题 如标题 参考 Redundant character escape in RegExp CodeAntenna 解决办法 将转义符号 删除掉
  • 【分布式金融交易模型】Seata中间件的TCC模式实现一对一转账

    Seata中间件实现一对一转账 1 转账界面 2 本地事务在分布式下的问题 2 1 本地事务 2 1 1 事务四大特性 2 1 2 本地事务的概念 2 1 3 本地事务的实现 使用注解 Transactional 2 1 4 事务的隔离级别
  • elastisearch启动报错:org.elasticsearch.cluster.block.ClusterBlockException: blocked by: [SERVICE_UNAVAIL

    使用命令启动一个ES进程 bin elasticsearch E node name warmnode E cluster name geektime E path data warm data E node attr my node ty
  • upload-labs第一关

    level1 根据提示这是本地js文件上传绕过 有两种思路 第一种将浏览器中的js检验代码删除 第二种 将一句话木马的后缀改成可以上传的文件类型 利用burp suit抓包再改包绕过js 改包过程 上传成功 获取上传的图片地址 在网页上打开
  • 计算机无法识别3.0u盘启动,USB3.0接口不能识别U盘的解决方法

    USB3 0接口不能识别U盘的解决方法 USB接口可以说是电脑的标配 现在基本上所有电脑都会搭载USB接口 而USB标准从1 0发展到现在的3 0 甚至更新的也已出来 不过 如果USB3 0无法识别U盘 那该怎么办呢 USB3 0是一种技术
  • tensorflow实战(五)——过拟合调参(2)及学习率动态调整

    我们通过采取动态调整学习率的策略 缓解过拟合问题 随着训练轮数的增加 学习率逐渐下降会使模型拟合的更好 在这里 我们设定网络结构为 model tf keras Sequential 0 255共256个 故第一个参数为256 数据为三位数
  • Docker(一)简介、环境搭建

    文章目录 一 docker简介 1 什么是docker 2 什么是容器 3 传统的虚拟化技术和容器之间的差别 4 容器运行的过程 重要 二 docker环境部署及测试 1 环境部署 2 通过镜像运行容器 3 拉取镜像 一 docker简介
  • Qt_QWidget窗体设置模态显示

    QWidget是Qt中的窗口类 实现QWidget窗口显示有三个步骤 1 实例化一个窗口类对象 类QWidget的对象可以是QWidget 也可以是QWidget的继承类 QWidget pW new QWidget NULL 2 调用函数
  • 物联网LoRa系列-28:LoRaWAN PingPong终端与Class A/B/C类型终端不能互通的原因与解决办法

    在LoRa终端与LoRa网关和服务器联调之前 有时候需要通过相对简单的PingPong终端序给Class A B C类型的终端发送数据 以验证Class A B C终端可以正常收发数据包 然而原生提供的 PingPong与Class A B
  • 怎么用VLC播放器将m3u8链接视频下载到本地

    m3u8格式链接在浏览器上打开 没有插件的情况下你会得到长得跟下面差不多的一个文本列表 有基础的同学可能知道 以 ts 结尾的那些就是视频连接的实际播放地址 当然你还要拼上前面的前缀 在浏览器上安装过插件的情况 你可以直接在线预览影片 但是
  • echarts设置柱形图宽度 最大宽度 最小宽度

    一般来说不需要设置柱形图宽度 不过如果实在是要设置也只能硬着头皮设置了 修改series对应数组里面的barWidth属性即可设置柱形图宽度 当然还有最小宽 最大宽则是barMinWidth和barMaxWidth api地址 https
  • 现在的00后,实在是太卷了,我们这些老油条都想辞职了......

    现在的小年轻真的卷得过分了 前段时间我们公司来了个00年的 工作没两年 跳槽到我们公司起薪20K 都快要超过我了 后来才知道人家是个卷王 从早干到晚就差搬张床到工位睡觉了 最近和他聊了一次天 原来这位小老弟家里条件不太好 一大家子指望他一个
  • ❤ npm install报错以及各种错误码的含义

    npm install报错以及各种错误码的含义 1 npm install 10054 报错 Error while executing 造成这个错误很有可能是网络不稳定 连接超时导致的 如果再次尝试后依然报错 可以执行下面的命令 打开Gi
  • 种类并查集+入门题A Bug's Life

    我觉得种类并查集还是先从一个基础入门题讲起吧 Background Professor Hopper is researching the sexual behavior of a rare species of bugs He assum