高阶数据结构---并查集

news2024/11/25 23:30:16


文章目录

  • 格子游戏
  • 搭配购买
  • 程序自动分析
  • 奇偶游戏
  • 银河英雄传说

一、格子游戏OJ链接

        本题思路:本题首先我们将题目中所给的二维坐标映射到一维坐标中,从坐标从0开始进行,而题目中是从1开始,我们需要先进行--操作,然后利用并查集来判断即可。

#include <bits/stdc++.h>

constexpr int N=40010;

int n,m;
int p[N];

int find(int x)
{
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	std::cin>>n>>m;

	for(int i=0;i<n*n;i++) p[i]=i;//并查集的初始化操作

	int res=0;
	for(int i=1;i<=m;i++){
		int x,y;
		char op;

		std::cin>>x>>y>>op;
		x--,y--;
		int a=x*n+y;//这里我们需要将二维坐标转换成一维坐标
		int b;
		if(op=='D') b=(x+1)*n+y;
		else b=x*n+y+1;

		int pa=find(a),pb=find(b);
		if(pa==pb)
		{
			res=i;
			break;
		}
		p[pa]=pb;
	}
	
	if(res==0) std::cout<<"draw"<<std::endl;
	else std::cout<<res<<std::endl;
	return 0;
}

二、搭配购买OJ链接

        本题思路:本题每行两个整数 ui,vi,表示买 ui就必须买 vi,同理,如果买 vi 就必须买 ui。这里就可以通过并查集的方式将两个整数合并到一个集合里面看成一个物品的方式,然后在有限的w的价格下买最大价值的商品这可以利用01背包问题求解。

#include <bits/stdc++.h>

constexpr int N=1e5+10;

int n,m,w;
int c[N],d[N];
int p[N];
int f[N];

int find(int x)
{
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}

void merge(int a,int b)//这里合并的时候需要将此时的集合内的所有元素看成一个就需要将价值和价钱合并
{
	int pa=find(a),pb=find(b);
	if(pa!=pb){
		p[pa]=pb;
		c[pb]+=c[pa];
		d[pb]+=d[pa];
	}
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	std::cin>>n>>m>>w;

	for(int i=1;i<=n;i++) p[i]=i;//并查集初始化动作
	for(int i=1;i<=n;i++) std::cin>>c[i]>>d[i];


	while(m--){
		int a,b;
		std::cin>>a>>b;
		merge(a,b);//合并操作
	}

	for(int i=1;i<=n;i++){//进行01背包处理
		if(i==p[i]){
			for(int j=w;j>=c[i];j--)
				f[j]=std::max(f[j],f[j-c[i]]+d[i]);
		}
	}

	std::cout<<f[w]<<std::endl;
	return 0;
}

三、程序自动分析OJ链接

        本题思路:由于数据范围是1e9次方,题中所给的变量范围1e5方,但是我们只需要合并2e5个这里我们就可以使用离散化解决问题。我们定义一个query来保存每一个问题方便我们最后一次扫描找出答案。如果i==j我们可以使用并查集解决问题。

#include <bits/stdc++.h>

constexpr int N=2e5+10;//由于题目中所给的数据范围为1e9所以我们需要进行离散化处理只需要合并2e5个

int n;
std::unordered_map<int,int> hash;//利用哈希来映射
int idx;

struct Query//表示操作关系
{
	int a,b,op;
}q[N];

int p[N];

int s(int x)//这里就是下标映射
{
	if(hash.count(x)) return hash[x];
	return hash[x]=++idx;
}

int find(int x)
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	int T;
	std::cin>>T;
	while(T--){
		idx=0;
		hash.clear();

		for(int i=1;i<=N;i++) p[i]=i;

		std::cin>>n;
		for(int i=1;i<=n;i++){
			int a,b,e;
			std::cin>>a>>b>>e;
			//首先进行离散化处理
			a=s(a),b=s(b);
			q[i]={a,b,e};
			if(e) //如果是1表示a和b相等此时需要进行合并
				p[find(a)]=find(b);
		}

		bool flag=true;
		for(int i=1;i<=n;i++){//扫描一遍
			if(!q[i].op){
				int a=q[i].a,b=q[i].b;
				if(find(a)==find(b)){
					flag=false;
					break;
				}
			}
		}

		if(flag) std::cout<<"YES"<<std::endl;
		else std::cout<<"NO"<<std::endl;
	}
	return 0;
}

四、奇偶游戏OJ链接

        本题思路:本题可以首先采用前缀和的思想,用sum数组表示序列S的前缀和,分为两种情况:第一种情况就是如果S[L~R]有偶数个1,则sum[L-1]和sum[R]奇偶性相同,第二种就是如果S[L~R]有奇数个1,则sum[L-1]和sum[R]奇偶性不同。由于本题序列长度很大而问题较少所以我们需要进行离散化处理。本题是多种传递关系,首先我们采用边带权的并查集解决。或者是采用扩展域并查集的方式解决。摘要这位大佬

#include <bits/stdc++.h>

constexpr int N=2e4+10;

int n,m;
int p[N],d[N];
std::unordered_map<int,int> hash;
int idx;

int s(int x)
{
	if(hash.count(x)) return hash[x];
	return hash[x]=++idx;
}

int find(int x)
{
	if(x!=p[x]){
		int root=find(p[x]);
		d[x]^=d[p[x]];
		p[x]=root;
	}
	return p[x];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	std::cin>>n>>m;

	for(int i=1;i<=N;i++) p[i]=i;

	int res=m;//如果没有矛盾则答案为所给的问题数量
	for(int i=1;i<=m;i++){
		int a,b;
		std::string type;
		std::cin>>a>>b>>type;
		a=s(a-1),b=s(b);//对s[a-1],s[b]进行离散化处理

		int t=0;//0表示该问题时奇数1表示偶数
		if(type=="odd") t=1;

		int pa=find(a),pb=find(b);
		if(pa!=pb)//如果离散化之后的a,b不在同一个集合则需要进行合并集合
		{
			p[pa]=pb;
			d[pa]=d[a]^d[b]^t;
		}
		else{
			if((d[a]^d[b])!=t){
				res=i-1;
				break;
			}
		}
	}

	std::cout<<res<<std::endl;
	return 0;
}

         

#include <bits/stdc++.h>

constexpr int N=2e4+10;
constexpr int Base=N/2;

int n,m;
int p[N],d[N];
std::unordered_map<int,int> hash;
int idx;

int s(int x)
{
	if(hash.count(x)) return hash[x];
	return hash[x]=++idx;
}

int find(int x)
{
	if(x!=p[x])p[x]=find(p[x]);
	return p[x];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	std::cin>>n>>m;

	for(int i=1;i<=N;i++) p[i]=i;

	int res=m;//如果没有矛盾则答案为所给的问题数量
	for(int i=1;i<=m;i++){
		int a,b;
		std::string type;
		std::cin>>a>>b>>type;
		a=s(a-1),b=s(b);//对s[a-1],s[b]进行离散化处理

		if(type=="even"){
			if(find(a+Base)==find(b)){
				res=i-1;
				break;
			}
			p[find(a)]=find(b);
			p[find(a+Base)]=find(b+Base);
		}
		else{
			if(find(a)==find(b)){
				res=i-1;
				break;
			}
			p[find(a+Base)]=find(b);
			p[find(a)]=find(b+Base);
		}
	}

	std::cout<<res<<std::endl;
	return 0;
}

五、银河英雄传说OJ链接

         本题思路:本题可以采用并查集,size[x]表示集合的大小,dist[x]表示x到p[x]的距离。将第a列的船接在第b列的末尾,相当于让每个点到pb的距离都加上size[pb],由于存储并查集中存在路径压缩的效果,因此只需要将pa到pb的距离加上size[pb]即可,即d[pa] = size[pb],其他跟着pa后面的元素的路径进行压缩且更新dist[i]的值。路径压缩首先找到根结点root,计算父节点到上一个父节点的距离dist[p[x]],同时进行路径压缩(路径压缩后,上一父节点即root),dist[x]初始值是x到p[x]的距离,更新dist[x]值,即dist[x] = dist[x] + dist[p[x]]。

#include <bits/stdc++.h>

constexpr int N=30010;

int p[N];
int size[N];//表示当前列包含的所有元素的个数
int dist[N];//表示某个元素到根的距离

int find(int x)
{
    if(p[x]!=x){
        int root=find(p[x]);
        dist[x]+=dist[p[x]];
        p[x]=root;
    }
    return p[x];
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);std::cout.tie(nullptr);

    int T;
    std::cin>>T;

    for(int i=1;i<=N;i++){
        p[i]=i;
        size[i]=1;
    }

    while(T--){
        char op;
        int a,b;
        std::cin>>op>>a>>b;

        int pa=find(a),pb=find(b);
        if(op=='M'){
            if(pa!=pb){
                dist[pa]=size[pb];
                size[pb]+=size[pa];
                p[pa]=pb;
            }
        }
        else{
            if(pa!=pb) std::cout<<-1<<std::endl;
            else std::cout<<std::max(0,std::abs(dist[a]-dist[b])-1)<<std::endl;
        }
    }
    return 0;
}

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

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

相关文章

技术分享 | Appium环境安装与架构介绍

Appium架构 Appium 设计哲学 不需要为了自动化而重新编译或修改被测应用 不应该让移动端自动化测试限定在某种语言或者某个具体的框架 不要为了移动端的自动化测试而重新造轮子 移动端自动化测试应该是开源的 Appium 架构 Appium 架构图如下&#xff1a; Appium 的核心是…

【数据库】数据库模式 Schema

数据库模式 Schema 1.MySQL2.PostgreSQL3.SQL Server4.Oracle5.SQLite 在数据库的术语中&#xff0c;模式&#xff08;schema&#xff09;是一个逻辑概念&#xff0c;用于组织数据库中的对象。模式中的对象通常包括 表、索引、数据类型、序列、视图、存储过程、主键、外键 等等…

STM32笔记—DMA

目录 一、DMA简介 二、DMA主要特性 三、DMA框图 3.1 DMA处理 3.2 仲裁器 3.3 DMA通道 扩展: 断言&#xff1a; 枚举&#xff1a; 3.4 可编程的数据传输宽度、对齐方式和数据大小端 3.5 DMA请求映像 四、DMA基本结构 4.1 DMA_Init配置 4.2 实现DMAADC扫描模式 实现要求…

代码随想录 Day38 完全背包问题 LeetCode T70 爬楼梯 T322 零钱兑换 T279 完全平方数

前言 在今天的题目开始之前,让我们来回顾一下之前的知识,动规五部曲 1.确定dp数组含义 2.确定dp数组的递推公式 3.初始化dp数组 4.确定遍历顺序 5.打印dp数组来排错 tips: 1.当求取物品有限的时候用0-1背包,求取物品无限的时候用完全背包 结果是排列还是组合也有说法,当结果是组…

设计模式之工厂模式(Factory)

任何可以产生对象的方法或类&#xff0c;都可以称为工厂。 下面的代码定义了Car这种交通工具: public class Car {public void go() {System.out.println("Car go wuwuwuwuw....");} }然后在main函数里面想要调用调用Car的go方法&#xff0c;就需要new一个car对象&…

Netty入门指南之传统通信的问题

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言多线程…

管理类联考——写作——技巧篇——书写标点符号使用要求规范文档

写作答题卡书写标点符号使用要求规范文档 常用标点符号有逗号、句号、叹号、问号等 11 种&#xff0c;下面一一列举其用法和书写规范。 一、句号 用法&#xff1a;用于陈述句的末尾。 占格情况&#xff1a;占一格&#xff0c;写在格子左下方。 举例&#xff1a; 我看见妈妈走…

web3案例中解决交易所中 ETH与token都是0问题 并帮助确认展示是否成功

可能写了这么久 很多人会发现一个问 我们前面的案例 个人在交易所中的 自定义token 和 ETH 一直是放了个0 大家也不太敢确认是否真的有效 那么 很简单 我们操作 存入一些进交易所 不就ok了 我们 来看之前交易所写的代码 我们写了 depositEther 存入 ETH 和 depositToken 存入…

03 贝尔曼公式

贝尔曼公式 前言1、Motivating examples2、state value3、Bellman equation:Derivation4、Bellman equation:Matrix-vector form4、Bellman equation:Solve the state value5、Action value 前言 本文来自西湖大学赵世钰老师的B站视频。本节课主要介绍贝尔曼公式。 本节课概要…

海外问卷项目是怎么赚钱的?

大家好&#xff0c;我是橙河老师&#xff0c;今天聊一聊海外问卷项目是怎么赚钱的&#xff1f; 在海外国家&#xff0c;问卷调查这种商业模式一直都很流行&#xff0c;很多商业公司为了收集消费者的意见&#xff0c;会对外发有偿的调查问卷&#xff0c;从最开始的纸质调查&…

MySQL第五讲·关于外键和连接, 如何做到关联查询?

你好&#xff0c;我是安然无虞。 文章目录 外键和连接&#xff1a;如何做关联查询&#xff1f;如何创建外键&#xff1f;连接关联查询中的误区 外键和连接&#xff1a;如何做关联查询&#xff1f; 在实际的数据库应用开发过程中&#xff0c;我们经常需要把2个或2个以上的表进…

C语言函数初使用

目录 1知识点&#xff1a; 2一个小代码&#xff0c;后续知识点讲解&#xff1a; 3知识点&#xff1a; 定义函数 实例 函数声明 调用函数 函数参数 4总结&#xff1a; 1知识点&#xff1a; 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数&#xff0c;…

网站源码备份 [极客大挑战 2019]PHP1

打开题目 题目提示我们备份网站 我们输入/www.zip 下载zip文件&#xff0c;打开发现 打开index.php <?phpinclude class.php;$select $_GET[select];$resunserialize($select);?> 文件包含class.php&#xff0c;get传参一个select函数&#xff0c;反序列化select参…

HMM与LTP词性标注之命名实体识别与HMM

文章目录 知识图谱介绍NLP应用场景知识图谱&#xff08;Neo4j演示&#xff09;命名实体识别模型架构讲解HMM与CRFHMM五大要素&#xff08;两大状态与三大概率&#xff09;HMM案例分享HMM实体识别应用场景代码实现 知识图谱介绍 NLP应用场景 图谱的本质&#xff0c;就是把自然…

JS逆向爬虫---请求参数加密②【某麦数据analysis参数加密】

主页链接: https://www.qimai.cn/rank analysis逆向 完整参数生成代码如下&#xff1a; const {JSDOM} require(jsdom) const dom new JSDOM(<!DOCTYPE html><p>hello</p>) window dom.windowfunction customDecrypt(n, t) {t t || generateKey(); //…

ZZULIOJ 1108: 打印数字图形(函数专题) (C/C++)

1108: 打印数字图形&#xff08;函数专题&#xff09; 题目描述 从键盘输入一个整数n(1≤n≤9),打印出指定的数字图形。要求在程序中定义并调用如下函数&#xff1a;PrintSpace(m)用来输出m个空格&#xff1b;PrintDigit(m)来输出一行中的数字串"12…m…21"&#xff…

element树形结构下拉组件组装对应格式数据

element树形结构下拉组件组装对应格式数据 <el-row><el-col :span"24"><el-form-item label"购买渠道" prop"treeData" class"grid-content bg-purple"><el-cascaderv-model"testForm.treeData":optio…

鳄鱼指标的3颜色线都代表什么?澳福官网一段话明白了

投资者一直在使用鳄鱼指标进行交易&#xff0c;但是对指标上面的3种颜色的K线都代表什么不明白&#xff1f;直到看到澳福官网一段话才明白&#xff0c;原来这么简单&#xff01; 鳄鱼指标&#xff0c;这一工具是由三条移动平均线组合而成。具体来说&#xff0c;蓝线&#xff0…

8-3、T型加减速单片机程序【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;根据前两节内容&#xff0c;已完成所有计算工作&#xff0c;本节内容介绍具体单片机程序流程及代码 一、程序流程图 根据前两节文章内容可知&#xff0c;T型加减速的关键内容是运动类型的判断以及定时器初值的计算&#xff0c;在输出运动参数后即可判断出运动…

前端代码优化小技巧

导读 今天分享一下开测前端代码的一些优化&#xff0c;及使用的一些小技巧&#xff0c;来优化我们的网站&#xff0c;前端开发中最常见的问题就是很少使用ES6方法导致代码冗余&#xff0c;不够清晰&#xff0c;定时器和闭包导致内存溢出及泄露,网站中css导致排版错乱&#xff…