并查集维护额外信息,算法思路类似前缀和,结构类似扑克接龙

一、链接

240. 食物链

二、题目

动物王国中有三类动物 A,B,CA,B,C,这三类动物的食物链构成了有趣的环形

AA 吃 BB,BB 吃 CC,CC 吃 AA。

现有 NN 个动物,以 1∼N1∼N 编号

每个动物都是 A,B,CA,B,C 中的一种,但是我们并不知道它到底是哪一种。

有人用两种说法对这 NN 个动物所构成的食物链关系进行描述:

第一种说法是 1 X Y,表示 XX 和 YY 是同类

第二种说法是 2 X Y,表示 XX  YY。

此人对 NN 个动物,用上述两种说法,一句接一句地说出 KK 句话,这 KK 句话有的是真的,有的是假的。

当一句话满足下列三条之一时,这句话就是假话,否则就是真话

  1. 当前的话与前面的某些真的话冲突,就是话;
  2. 当前的话中 XX 或 YY  NN 大,就是话;
  3. 当前的话表示 XX 吃 XX,就是话。

你的任务是根据给定的 NN 和 KK 句话,输出假话的总数

输入格式

第一行是两个整数 NN 和 KK,以一个空格分隔。

以下 KK 行每行是三个正整数 D,X,YD,X,Y,两数之间用一个空格隔开,其中 DD 表示说法的种类。

若 D=1D=1,则表示 XX 和 YY 是同类。

若 D=2D=2,则表示 XX 吃 YY。

输出格式

只有一个整数,表示假话的数目。

数据范围

1≤N≤500001≤N≤50000,
0≤K≤1000000≤K≤100000

输入样例:

100 7
1 101 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5

输出样例:

3

三、题意

总共有三种生物,构成一个吃与被吃的闭环,给出多个描述,判断假话的个数并输出

四、代码

#include<iostream>using namespace std;const int N=50000+10;int p[N],d[N];int find(int x)
{if(p[x]!=x){int t=find(p[x]);d[x]+=d[p[x]];p[x]=t;}return p[x];
}int main()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){p[i]=i;}int res=0;while(m--){int t,x,y;scanf("%d%d%d",&t,&x,&y);if(x>n||y>n){res++;}else{int px=find(x),py=find(y);if(t==1){if(px==py&&(d[x]-d[y])%3){res++;}else if(px!=py){p[px]=py;d[px]=d[y]-d[x];}}else{if(px==py&&(d[x]-d[y]-1)%3){res++;}else if(px!=py){p[px]=py;d[px]=d[y]-d[x]+1;}}}}printf("%d\n",res);return 0;
}

五、总结

1.首先我为什么说这里使用并查集和前缀和的思路类似呢,因为我们在这里使用一个类似预处理的操作,把每一个结点到根节点的距离计算了出来,然后判断这两个节点的距离即可,前缀和是预处理前面的和,然后对两个点的和进行差运算,感觉是差不多的。

2.我们除了合并属于不同集合的元素,还需要维护一些额外的信息,比如说每一个节点到根节点的距离,怎么表示两个元素之间的关系呢,可以看它与根节点之间的距离。

3.先给出一个并查集的模板:并查集模板-两个操作:合并集合和查询两个元素是否属于同一个集合

4.还是有一个问题,就是我们改变一个变量的时候要注意,是否之前对他进行了修改,修改之后我们这样写会报错,所以最好是先把需要使用的变量用一个临时变量存下来,就是这里的几行代码需要注意给这个问题

int t=find(p[x]);
d[x]+=d[p[x]];
p[x]=t;

如果先改变根节点,根节点重合,原来元素到根节点的距离就会发生变化,但是我们需要之前元素到修改之前根节点的距离,所以需要先把根节点拿出来保存,先修改结点到根节点的距离,再修改根节点 

总结就是遇到类似的问题,最好就是把变量拿出来,防止修改之后发生变化,出现错误

5.这个题目需要进行的条件判断比较多:首先是正常的初始化,就是并查集的简单初始化,需要注意的是最开始每一个元素自己相当于根节点,到根节点的距离是0,定义为全局变量,不需要进行初始化。

6.如果第二个或者第三个输入的元素大于输入的总数n,那么就要把假话数字增加一,除去这种情况,再开始讨论别的情况

7.如果是表示的两个属于同类,需要进行两个判断,第一个判断是这两个动物是不是属于同一个集合(并查集的特性),如果属于同一个集合并且两个动物(或者说结点)不是同一类物种(到根节点之间的距离对3进行取模之后的数值不相等),就说明不是真话,res++;如果不属于同一个集合,说明两个元素的集合不是同一个集合,就需要把两个元素合并到同一个集合里面,还需要更新里面结点到根节点的距离,因为根节点发生了变化。在最开始条件判断之前,先把输入的第二个数,第三个数的根节点拿了出来,存在px,py里面,现在更新的话,其实不用太考虑顺序,直接更新结点和距离就可以。更新节点使用这一行代码

p[px]=py;

更新距离需要思考一下,原来结点到根节点的距离是d[x],另一个结点到它的根节点的距离是d[y],我们现在把x的根节点指向了y的根节点,现在y的根节点变成了总的根节点,x和y属于同类,那么他们两个元素到根节点的距离取模之后是相等的,现在x到根节点的距离是d[x]+d[px],d[px]表示的是x的根节点到现在新的根节点的距离,d[x]+d[px]-d[y]取模之后的结果应该是等于0,所以把距离更新的代码就是这样写

d[px]=d[y]-d[x];

 8.另外一种情况是x吃y:并查集里面的树状结构有点像扑克接龙游戏,只能是固定的顺序,一层可以有很多同类的,但是新的不同类的必须在下一层,假设根节点是A,然后B吃A,是第一层,C吃B,是第二层,D和A同类,排在第三层,可以吃C,也可以被B吃,如果再来一个A的同类,这个时候还是排在第三层,如果是x吃y,x假设紧靠着y的话,是排在y的下一层,取模来看的话,是模3之后比y到根节点的距离模3之后大1。分两种情况,第一种情况,x和y在一个并查集里面,并且这两个节点的到根节点的距离的差减去1对3取模(d[x]-d[y]-1)%3不等于0,表示这两个元素不符合x吃y,说明是假话,就把答案增加1。第二种情况是,两个元素不属于同一个并查集,就需要更新根节点和距离,因为在最开始的时候,把两个元素的根节点取出来存在临时变量px,py中,现在操作只需要把根节点更新,把距离更新就行,顺序不需要考虑,更新之后d[x]==d[px]+d[x],应该还是要满足(d[x]-d[y]-1)%3==0,d[px]+d[x]-d[y]-1=0,所以d[px]=d[y]+1-d[x];

9.最后输出答案即可

10.这个题目还是蛮复杂的,抽象的来理解还是比较简单,但是具体构建这个模型,讲述清楚还是比较难,也有可能是我太弱了(肯定是的哈哈)。树状结构真的抽象!简单的来说就是并查集+维护一个到根节点的距离,维护距离的时候注意根节点会发生变化,最好把根节点用临时变量先存起来,再更新根节点和距离

六、精美图片

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/25462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

总结950

7:00起床 7:30~8:00复习单词300个&#xff0c;记忆100个 8:10~9:30数学660&#xff0c;只做了10道题&#xff0c;发现对各知识点的掌握程度不一。有些熟练&#xff0c;有些生疏 9:33~10:25计算机网络课程1h 10:32~12:02继续660&#xff0c;也不知道做了几道 2:32~4:00数据…

12.物联网操作系统之多任务核心

一。列表及列表项概念以及应用 1.freeRTOS列表介绍 列表项都是由链表生成&#xff0c;想要了解列表项&#xff0c;首先应该把上述的链表都要搞懂。 这是列表项的组件列表。 2.列表及列表项的定义 列表是双向链表构成&#xff0c;原因是双向链表的插入与删除效率高&#xff0c…

【Spring】使用注解的方式获取Bean对象(对象装配)

目录 一、了解对象装配 1、属性注入 1.1、属性注入的优缺点分析 2、setter注入 2.1、setter注入的优缺点分析 3、构造方法注入 3.1、构造方法注入的优缺点 二、Resource注解 三、综合练习 上一个博客中&#xff0c;我们了解了使用注解快速的将对象存储到Spring中&#x…

Android:自己写一个简单记事本

一、前言&#xff1a;我的app是点击加号跳转到另一个界面 那么我遇到的问题的是点击加号是一个从一个Fragment跳转到另一个Fragment跳转失败。 二、解决方案&#xff1a; //相应控件的监听里面实现跳转FragmentManager fragmentManagergetFragmentManager();fragmentManager.b…

网络可靠性之链路聚合

网络的可靠性 网络的可靠性指当设备或者链路出现单点或者多点故障时保证网络服务不间断的能力网络的可靠性是可以从单板、设备、链路多个层面实现。 链路聚合 以太网链路聚合&#xff1a; 通过将多个物理接口捆绑成为一个逻辑接口&#xff0c;可以再不进行硬件升级的条件下&a…

css滚动条样式指南

css滚动条样式指南 滚动条是网页设计中经常被忽视的元素。虽然它看起来像是一个小细节&#xff0c;但它在网站导航中起着至关重要的作用。默认的滚动条可能看起来不合适&#xff0c;有损整体美观。本文将介绍如何使用 CSS 自定义滚动条。 在 Chrome、Edge 和 Safari 中设置滚…

基于Azure OpenAI Service 的知识库搭建实验⼿册

1.概要 介绍如何使⽤Azure OpenAI Service 的嵌⼊技术&#xff0c;创建知识库&#xff1b;以及创建必要的资源组和资源&#xff0c;包括 Form Recognizer 资源和 Azure 翻译器资源。在创建问答机器⼈服务时&#xff0c;需要使⽤已部署模型的 Azure OpenAI 资源、已存在的…

SAP-MM-发票校验的重复校验功能

路径&#xff1a;SPRO-物料管理-后勤发票校验-收入发票-设置重复发票检查 按公司代码设置重复检查&#xff0c;可以按三个方式进行检查&#xff0c;公司代码、参照、发票日期&#xff0c;如果此处未维护就是按供应商&#xff08;XK02&#xff09;的六项进行检查 但是如果两处都…

深入学习 Redis - 事务、实现原理、指令使用及场景

目录 一、Redis 事务 vs MySQL事务 二、Redis 事务的执行原理 2.1、执行原理 2.2、Redis 事务设计这么简单&#xff0c;为什么不涉及成 MySQL 那样强大呢&#xff1f; 三、Redis 事务的使用 3.1、使用场景 3.2、具体演示 开启/执行/放弃事务 watch 监控 watch 实现原理…

chapter14:springboot与安全

Spring Boot与安全视频 Spring Security, shiro等安全框架。主要功能是”认证“和”授权“&#xff0c;或者说是访问控制。 认证&#xff08;Authentication&#xff09;是建立在一个声明主体的过程&#xff08;一个主体一般指用户&#xff0c;设备或一些可以在你的应用程序中…

Django之JWT库与SimpleJWT库的使用

Django之JWT库与SimpleJWT库的使用 JWTJWT概述头部(header)载荷(payload)签名(signature) Django使用JWT说明jwt库的使用安装依赖库配置settings.py文件配置urls.py文件创建视图配置权限 SimpleJWT库的使用安装SimpleJWT库配置Django项目配置路由创建用户接口测试身份认证自定义…

【雕爷学编程】Arduino动手做(190)---MAX4466声音模块

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

Jenkins Gerrit Trigger实践

1.创建Gerrit Trigger 2.jenkins master节点生成gerrit用户的密钥 这里的用户名得写登录gerrit后个人信息中的 Username 3.gerrit 配置刚刚jenkins生成密钥的公钥 4.gerrit 用户加入群组 不加这个群组&#xff0c;下一步测试就会报错“User aeshare has no capability conn…

Dueling Network

Dueling Network —— Dueling Network Architectures for Deep Reinforcement Learning 论文下载地址 论文介绍 图9. Dueling Network 模型结果示意图 Dueling Network与传统DQN的区别在于神经网络结构的不同&#xff0c;Dueling Netowrk在传统DQN的基础上只进行了微小的改动…

Flowise AI:用于构建LLM流的拖放UI

推荐&#xff1a;使用NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 什么是Flowise AI&#xff1f; Flowise AI是一个开源的UI可视化工具&#xff0c;用于帮助开发LangChain应用程序。在我们详细介绍 Flowise AI 之前&#xff0c;让我们快速定义 LangChain。LangChain是…

MapTR论文笔记

MAPTR: STRUCTURED MODELING AND LEARNING FOR ONLINE VECTORIZED HD MAP CONSTRUCTION 目的 传统高精地图 通过一些离线的基于 SLAM 的方法生成&#xff0c;需要复杂的流程以及高昂的维护费用。基于 bev 分割的建图方法&#xff0c;缺少向量化 实例级的信息&#xff0c;比如…

基于Vue+wangeditor实现富文本编辑

目录 前言分析实现具体解决的问题有具体代码实现如下效果图总结前言 一个网站需要富文本编辑器功能的原因有很多,以下是一些常见的原因: 方便用户编辑内容:富文本编辑器提供了类似于Office Word的编辑功能,使得那些不太懂HTML的用户也能够方便地编辑网站内容。提高用户体验…

从零开始实现一个 mini-Retrofit 框架

前言 本篇文章将采用循序渐进的编码方式&#xff0c;从零开始实现一个Retorift框架&#xff0c;在实现过程中不断提出问题并分析实现&#xff0c;最终开发出一个mini版的Retrofit框架 演示一个使用OkHttp的项目Demo 为了更好的演示框架的实现过程&#xff0c;这里我先创建了一…

Compose应用案例(利用docker compose安装lnmp实例)

目录 Compose应用案例 一、前提配置 &#xff08;一&#xff09;安装docker-ce&#xff08;Linux安装Docker&#xff09; &#xff08;二&#xff09;安装docker-compose 二、安装docker compose部署lnmp &#xff08;一&#xff09;目录结构&#xff1a; &#xff08;二…

SPM(Swift Package Manager)开发及常见事项

SPM怎么使用的不再赘述&#xff0c;其优点是Cocoapods这样的远古产物难以望其项背的&#xff0c;而且最重要的是可二进制化、对xcproj项目无侵入&#xff0c;除了网络之外简直就是为团队开发的项目库依赖最好的管理工具&#xff0c;是时候抛弃繁杂低下的cocoapods了。 一&…