【算法每日一练]-图论(保姆级教程篇10 并查集)#POJ1988 #POJ1182

目录

POJ1988

        思路:

POJ1182

        思路:


        

        

        

POJ1988

有n个栈每个栈中有一个方块,现要执行n次操作。一种是移数,一种是计数
移数M:把包含x的栈整体移动到y栈顶
计数C:统计X方块下面的方块数

输入:
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

        
思路:

我们不需要模拟,我们只需要等价即可,每次操作无非是把一个链表接到了另一个链表上,这完全可以用并查集实现。

        

设置fa数组表示集合号,cnt表示x号栈中的数量,d为x下方的数量

        
移数就等价与并查集的合并建树的过程。我们设置祖宗是栈底的方块,然后一边维护fa,cnt,d数组即可。

值得注意的是,这三个数组我们都只需要在祖宗那里标记一下就行,然后查找的时候再去更新(类似分块和线段树中懒标思想)。

        
然后查找祖宗的时候也就是回溯时候既要更新fa(根据祖宗更新),也要更新每个点的d值(根据亲爹更新),(不用更新cnt都一样更新啥呀)

        


#include <bits/stdc++.h>
using namespace std;
const int N=30005;
int n,fa[N],d[N],cnt[N];//d[x]是x下方的数量,cnt[x]是x号栈中的数量void init(){for(int i=1;i<N;i++){fa[i]=i; d[i]=0; cnt[i]=1;}
}
//很多时候每个点都要设置d值的,来代表深度
int find(int x)
//我们设置祖先是栈底方块,在查找的时候更新fa和d:fa[x]=find(fa[x])   d[x]=d[x的亲爹]
{int fx=fa[x];//保存亲爹if(x!=fa[x]) {//x自己不是祖宗,就要让fa[x]更新成祖宗的集合号fa[x]=find(fa[x]);d[x]+=d[fx];//必须让亲爹先是正确的,所以放在dfs之后}return fa[x];//返回祖先 
}void unity(int x, int y)//我们要让祖宗能代表整个栈,所以就为祖宗设置cnt
{int f1=find(x);int f2=find(y);fa[f1]=f2;//走到栈底了,进行合并,x栈放在y栈上面d[f1]=cnt[f2]; //更新x栈祖宗f1的d,因为只需要把根更新正确即可cnt[f2]+=cnt[f1];//更新y的祖宗f2的cnt
}int main(){char ch;int i,j;cin>>n;init();while(n--){getchar();//cin,scanf的除了字符型都不怕空格和回车死不掉,但是只管过滤前面的,后面不管scanf("%c",&ch);if(ch=='C'){scanf("%d",&i);int fi=find(i);//必须先查一边,fi没用的printf("%d\n",d[i]);}else{scanf("%d%d",&i,&j);unity(i,j);}}
}

        

        

        

POJ1182

有三类动物ABC,A吃B,B吃C,C吃A。现有n只动物(1~n编号),每个动物都是ABC的一种,但是我们并不知道它具体是哪一种。
有两种说法对这n个动物构成的食物链关系进行描述:
第一种说法:1 x y (表示x和y是同类)
第二种说法:2 x y (表示x吃y)
每句话满足以下三条之一就是假话,否则是真话。
1,当前话与前面的某些话冲突,此句话是假话
2,当前话x或y比n大,就是假话
3,当前话x吃x,就是假话                    请输出假话的数量

输入:
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

        
思路:

第2个最好判断。主要是第1,3个话。

并查集的优势是能快速帮你找到关系的祖宗fa和关系的层数d(深度)。而这道题就是利用关系层级解题的。

我们发现直接节点如果构成一条链的话,一定会3种动物进行循环。那么也就是说会形成大量的环。所以如果两种动物本来就在同一个集合的话就不需要合并了

首先判断吃

如果x和y在同一个集合中且x吃y的话:

(d[x]-d[y]+3)%3=1即可说明是正确的,因为可能有负值所以要多加3。(参考循环队列嘛)

如果不在同一个集合中:

那就fa[x]=y;(d[y]-d[x]+3)%3=1也说明正确。

        

然后判断同类:

如果x和y在同一个集合中的话:

(d[x]-d[y]+3)%3=0即可说明是正确的,因为可能有负值所以要多加3。

如果不在同一个集合中:

那就fa[x]=y;(d[y]-d[x]+3)%3=0也说明正确。

分析样例:

首先2 1 2,2 2 3 那么构成的并查集为

fa[1]=2 , d[1]=1     查询后变成- >fa[1]=2 , d[1]=2    

fa[2]=3 , d[2]=1                           fa[2]=3 , d[2]=1

fa[3]=3 , d[3]=0                           fa[3]=3 , d[3]=0

然后2 3 3 直接错误。

然后1 1 3 明显不是同类, (d[x]-d[y]+3)%3=2 错误

然后2 3 1  (d[x]-d[y]+3)%3=1 正确

然后1 5 5  (d[x]-d[y]+3)%3=0 正确

        

然后我们再优化一下:

如果是在不同集合的话,无论是查,还是吃,都需要合并建边不用判断。

但是如果在同一个集合中,无论是吃和是查只需要判断就行。还合并什么呀

        

那么在同一个集合中,判断公式为:(d[x]-d[y]+3)%3!= c - 1

明显x和y是吃时,c为2时应该和1比较,c为1时应该和0比较。

在不同集合中,合并公式为:fa[a]=b , d[a]=(d[y]-d[x]+3+c - 1)%3

        

#include <bits/stdc++.h>
using namespace std;
const int N=50010;
int n,fa[N],d[N];void init(){for(int i=1;i<=n;i++){fa[i]=i;d[i]=0;}
}int find(int x){int fx=fa[x];if(x!=fa[x]){fa[x]=find(fa[x]);d[x]=(d[x]+d[fx])%3;}return fa[x];
}int main(){int k,c,x,y,tot=0,a,b;scanf("%d%d",&n,&k);//n个动物,k个描述init();while(k--){scanf("%d%d%d",&c,&x,&y);if(x>n||y>n||(c==2&&x==y)) tot++;else {a=find(x),b=find(y);if(a==b){if((d[x]-d[y]+3)%3!=c-1) tot++;}else{fa[a]=b;d[a]=(d[y]-d[x]+3+c-1)%3;}}}cout<<tot<<'\n';	
}

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

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

相关文章

Pandas进阶:分类数据处理

引言 category是pandas的一种分类的定类数据类型。和文本数据.str.<methond>一样&#xff0c;它也有访问器功能.cat.<method>。 本文将介绍&#xff1a; 什么是分类数据&#xff1f; 分类数据cat的处理方法 为什么要使用分类数据&#xff1f; 分类数据cat使用…

Vue系列:页面中图片等静态资源引用

前言 近期在做项目时遇到一些图片、视频、动态图片等静态资源的使用&#xff0c;在vue页面jsx、tsx中使用的时候遇到些问题&#xff1b; 对静态资源的引用使用总结如下 引入方式说明 以下代码实例以图片、vue环境为例&#xff0c;不放视屏等引入实例&#xff0c;视频使用方式…

C++标准模板(STL)- 类型支持 (杂项变换,定义适于用作给定大小的类型的未初始化存储的类型,std::aligned_storage)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实…

记录5款NodeJS后端框架

文章目录 前言一、Express二、Nest.js三、Meteor四、Koa.js五、Fastify 前言 https://xie.infoq.cn/article/d8c2cd9cb99a04cbbf0a45434 https://juejin.cn/post/6959583458779725860 Nodejs 框架分为三种类型&#xff1a; MVCREST APIFull-Stack 一、Express Express 是最…

uni-app 微信小程序 电子签名及签名图片翻转显示功能

文章目录 1. 需求背景2. 开始撸2.1 点击 重写 进入签名页面&#xff08;上图一&#xff09;2.2 书写签名&#xff0c;点击确认返回&#xff0c;及图片翻转显示&#xff08;上图二&#xff0c;三&#xff09; 3. 图片进行翻转&#xff0c;返回翻转后的图片 1. 需求背景 接的一个…

Hdoop学习笔记(HDP)-Part.6 安装OracleJDK

六、安装OracleJDK 下载jdk安装文件&#xff0c;放到/opt中&#xff0c;将文件解压到/usr/local下后&#xff0c;修改/etc/profile文件中环境参数&#xff0c;实现java的安装。 创建jdk.yml文件 ---- hosts: alltasks:- name: copy and unzip jdkunarchive:src: "/opt/j…

C++学习之路(十五)C++ 用Qt5实现一个工具箱(增加16进制颜色码转换和屏幕颜色提取功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《Base64图片编码预览功能》功能。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加两个平时经常用到的功能吧&#xff0c;就是「 16进制颜色码转RGB文本 」和 「屏幕颜色提取」功能。下面我们就来看看如何来规划…

深入解析SpringBoot的请求响应机制

SpringBootWeb请求响应 前言1. 请求1.1 Postman介绍 1.2 简单参数1.2.1 原始方式1.2.2 SpringBoot方式1.2.3 参数名不一致 1.3 实体参数1.3.1 简单实体对象1.3.2 复杂实体对象 1.4 数组集合参数1.4.1 数组1.4.2 集合 1.5 日期参数1.6 JSON参数1.7 路径参数 2. 响应2.1 Response…

电子学会C/C++编程等级考试2021年06月(四级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:数字三角形问题 (图1) 图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 注意:路径上的每一步只能从一个数走到下一层上和它…

【微服务 SpringCloudAlibaba】实用篇 · Gateway服务网关

微服务&#xff08;8&#xff09; 文章目录 微服务&#xff08;8&#xff09;1. 为什么需要网关2. gateway快速入门1&#xff09;创建gateway服务&#xff0c;引入依赖2&#xff09;编写启动类3&#xff09;编写基础配置和路由规则4&#xff09;重启测试5&#xff09;网关路由的…

LeetCode22. 括号生成

参考的题解 &#x1f517;:链接22. 括号生成 class Solution {public List<String> generateParenthesis(int n) {List<String> result new ArrayList<>();backtracking(n, result, 0, 0, "");return result;}private void backtracking(int n, …

python之logo编程

Logo标志是一种视觉符号&#xff0c;代表着一个品牌、企业或组织的形象。它通常采用图形、字母或字形来代表一个公司或品牌&#xff0c;起到对徽标拥有公司的识别和推广的作用。Logo的设计需要考虑多种因素&#xff0c;例如颜色搭配、字体选择和构图等&#xff0c;以创造出独特…

java餐饮刀削面快餐店点餐服务系统springboot+jsp

网上点餐省去了客户很多不必要的时间和麻烦&#xff0c;给商家带来更多利益。同时&#xff0c;网上点餐可以辅助餐饮企业营销。传统的点餐是需要配备一个专业的服务员负责菜品介绍并记录顾客点单&#xff0c;确认后上交至后台厨房&#xff0c;厨房根据菜品种类安排做菜顺序最终…

11.28 C++作业

提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 要求使用C风格字符串完成 #include <iostream>using namespace std;int main() {string str;cout << "请输入一个字符串&#xff1a;" <<…

前端面试灵魂提问-计网(2)

1、websocket 为什么全双工? 1.1 WebSocket是什么 WebSocket 是一种通信协议&#xff0c;它在客户端和服务器之间建立持久的全双工连接。全双工意味着数据可以双向流动&#xff0c;即客户端可以向服务器发送消息&#xff0c;服务器也可以向客户端发送消息&#xff0c;而无需…

Hertz 整合swagger

文章目录 Swagger安装使用用法项目demoSwagger注释用法通用API信息 swag命令行参数swagger路由配置 Swagger 安装 go get 安装可执行文件需要配合 GOPATH 模式工作。 go get github.com/swaggo/swag/cmd/swag 因为从 Go 1.17 开始&#xff0c;在 go mod 模式下通过 go get 下…

Go 语言中 sync 包的近距离观察

让我们来看看负责提供同步原语的 Go 包&#xff1a;sync。 sync.Mutex sync.Mutex 可能是 sync 包中被广泛使用的原语。它允许对共享资源进行互斥操作&#xff08;即不允许同时访问&#xff09;&#xff1a; mutex : &sync.Mutex{}mutex.Lock() // Update shared variab…

Jinja2使用Layui报 “d is not defined“

问题出现场景在使用Jinja2渲染Layui的表格时候&#xff0c;要做自定义templte的传入 Jinja2这块本来就是支持 {{ }} 插值的模板语言&#xff0c;所以这块的第一种渲染方式会冲突 所以只能用函数返回代码块进行填充&#xff0c;不能使用插值&#xff0c;只能拼接字符串 templt…

Gradle windows下配置

1.Gradle下载 打开官网下载界面&#xff1a;https://gradle.org/releases/ 如果你使用的SpringBoot项目&#xff0c;建议使用6.8及以上的版本 2.下载后放到目录下 3.配置环境变量 配置gradle_home 配置Path 4.配置成功 5.配置国内源 新建一个init.gradle文件&#xff0c;配…

MySQL- CRUD-单表查询

一、INSERT 添加 公式 INSERT INTO table_name [(column [, column...])] VALUES (value [, value...]); 示例&#xff1a; CREATE TABLE goods (id INT ,good_name VARCHAR(10),price DOUBLE ); #添加数据 INSERT INTO goods (id,good_name,price ) VALUES (20,华为手机,…