并查集
陈末iiiiiiiiiiii
Retired
展开
-
POJ - 1703 种类并查集 带权并查集
题目题解思路因为是提示不同帮派,所以不能用普通的并查集来解决。注意的 点就是 不同帮派的人的不同帮派就是同一个帮派的。很容易想到带权并查集来解决,两个状态0 1 代表相同和不同帮派。这里还有种用朴素并查集实现的种类并查集可以解决这种问题。开两倍的空间,利用n外的数来附加n内的数的状态。记 a b c b 相连我们不直接让 a b 相连 ,让 a和 b+n b和 a+n相连。 c b+n c+n b相连这时就会有路径压缩使得a和c相连了,这样说明a c有间接的关系。AC代码普通并查原创 2021-07-26 17:13:33 · 183 阅读 · 2 评论 -
POJ - 1456 利用并查集进行优化 + 贪心
题目题解思路必然是贪心,但是贪心策略想不出,还是太弱了,这题朴素贪心居然也能过,数据太弱了。从大佬的博客 看到的贪心策略。将商品的价格从大到小排序,每次让商品从过期时间往前选择,这样对其他商品造成的影响就是最小的。用朴素的方法的话,时间复杂度为 N平方 数据为1e4 应该要到极限才对。我们可以用并查集优化, 将空闲的时间连接起来,因为进行了路径压缩,所以能节省复杂度。将时间数组初始化为 -1 。每次使用时,对时间进行find,返回离节点最近的空闲时间,使用后将时间指向时间-1的节点。原创 2021-05-26 19:17:14 · 93 阅读 · 0 评论 -
HDU - 1272 并查集判定图是否为树 坑点挺多
题目题解思路当在已为同一棵树里再加边时,可以判断不为树。再加上树的性质 : 点的数量等于边数减一 (判定非连通图)这两个条件加上去就可以AC了坑点0 0 为Yes1 2 2 1 (自环)这条可以用第一个条件筛去 这样只要特判0 0即可!AC代码#include <iostream>#include <cstdio>#include <cstring>using namespace std;int a[100010];bool un[原创 2021-05-26 16:50:53 · 77 阅读 · 0 评论 -
POJ - 1984 曼哈顿距离 + 带权并查集 + 分解双权值
题目题解思路还没碰到过曼哈顿距离 了解下曼哈顿距离:表示两个点在标准坐标系上的绝对轴距之和很自然的想到将X,Y的距离分别存一个权值数组,因为两者都存在正负情况,这样的话就有4种情况,只用一个数组不好处理。先把关系存起来,因为询问时限制了使用关系的大小和顺序。(一开始没看懂题目意思)这样只要在合并的时候分清用权值合并哪个就好了。其他的就是带权并查集模板了。坑点这里的查询数C是不会往下减的 (也就是在查询时不用每次都初始化)多组输出,需要在每两组输出间空一行!AC代码#includ原创 2021-05-25 18:00:20 · 199 阅读 · 0 评论 -
POJ - 2912 石头剪刀布 带权并查集 + 枚举 写了挺久的
题目n个小伙伴进行猜拳有戏,除了一个比较聪明的家伙(小法官)以外,其他人只会出单一的一种,给出m中猜拳的结果,要求找出那个比较聪明的小伙伴序号,并且输出在第几次猜拳可以确定。(注意<,>,=前后可能有空格)法官可能不止一个,不止一个的时候输出 Can not determine法官可能不存在,不存在的时候输出 Impossible法官可以确定为一个时,输出法官的编号和在最少在第几次猜拳可以确定。题解思路因为没有比较好的翻译加上这题意思含糊不清导致写了很久。看了别人的题解,基本原创 2021-05-25 16:37:42 · 171 阅读 · 0 评论 -
POJ - 2492 带权并查集模板 多组输入切莫忘记初始化
题目题解思路0和1代表两种类型,当两个点权值差距为0时,就是找出BUG了。合并入树和压缩路径时对2取模即可。带权并查集模板坑点多组输入权值数组和祖先数组要初始化!AC代码#include <iostream>#include <cstdio>#include <map>using namespace std;int a[2010];int w[2010];int find2 (int x){ if ( x != a[x] )原创 2021-05-25 09:44:23 · 103 阅读 · 0 评论 -
POJ - 1733 带权并查集 模运算 利用map进行离散化 题目没看全导致疯狂WA
题目题解思路题目意思要开1e9的数组,但是这样会超限。要对输入的数据进行离散化处理。利用map构建一个hash映射。因为原来的序列的长度编号并没有对序列产生影响,例如 下图中1 10 1中 插入个 3 10 1 并此时3的编号为4,并没有让题目的数据关系产生改变!然后就是带权并查集了,根据之前的区间处理小技巧,要让左区间先自减,让两边闭合的区间变成左开右闭。然后就是维护这个树了,在两个点都在树里就能判断,没有就合并入树。因为题目只存在奇数或者偶数的情况,所以进行模运算,0代表偶数,1代表奇数。原创 2021-05-25 09:09:15 · 186 阅读 · 2 评论 -
POJ - 1182 食物链 带权并查集 巧妙的模运算 大佬的思路
题目题解思路参考上一篇文章中大佬的带权并查集博客感觉这题能用一般并查集写,想了很久还是没有思路,换成带权并查集还是卡了很久。结果这题大佬讲了。运用模运算使权值的都在3一下,这样就可以代表分别输入哪个种类。再运用权值相减来判断是否合法。手模了几次。代码像是在维护一棵2层的树或者3层的树。一颗树树顶只有一个源点。当值没在树里是无法判断的,就有先合并进树的操作。这题卡cin和多组。AC代码#include <iostream>#include <cstdio>原创 2021-05-24 17:37:02 · 73 阅读 · 0 评论 -
HDU - 3038 带权并查集的学习 区间处理小技巧
题目题解思路有关带权并查集的学习 参考大佬的文章有关带权并查集的一些理解首先,带权需要多开一个带权的数组来处理权值。带权并查集的find 增加了对权值的更新 自带压缩路径int find2(int x){ if (x != a[x]) { int t = a[x]; //暂存父节点 a[x] = find2(a[x]); //寻找根节点并且合并 w[x] += w[t]; //找到根节点后 不断将根节点前的点的权值累加并更新 } //(递归思想) 最后x原创 2021-05-22 18:58:24 · 219 阅读 · 4 评论 -
HDU - 1213 并查集模板 统计无关的集合的数量 find请记得return
题目题解思路直接上并查集模板,初始化答案为 n ,每次合并的时候自减,最后输出就是正确答案了。可以理解为 每次合并一个人省了一条凳子 。一开始大家没有合并所以为 n 。AC代码#include <iostream>using namespace std;int a[1010];int ans ;int n,m;int find2(int x){ int r = x,t; while(r != a[r]) r = a[r] ; wh原创 2021-05-22 17:07:14 · 69 阅读 · 0 评论 -
POJ - 1611 并查集 模板 遍历累加 垃圾翻译坑人样例 我吐了
题目题解思路全部有关系的人都用并查集集合起来, 然后遍历父节点数组,有和0号一样的祖先的就累加即可,这里要压缩路径,以便以后的遍历父节点数组。这里翻译给了个坑人的样例,害我差点怀疑自己,翻译的样例不能信啊!!!!AC代码#include <iostream>#include <cstdio>#include <vector>#include <map>using namespace std;int n,m;int a[30010];i原创 2021-05-22 16:49:59 · 84 阅读 · 0 评论 -
CodeForces115A 该公司将举办一场聚会 DFS 并查集变式 寻找深度最高的树
题目一家公司拥有 n 名雇员,编号从 1 到 n 。每名雇员要么没有直接上司,要么只有一位直接上司 (直接上司是另一名具有不同编号的雇员)。如果满足以下条件之一,那么一名雇员 A 就被称之为另一名雇员 B 的 主管:雇员 A 是雇员 B 的直接上司;雇员 B 的直接上司是雇员 C,而雇员 A 是雇员 C 的主管。该公司在管理上不会形成层级循环。换言之,不会存在一名雇员是他/她自己的直接上司的主管。今天,该公司将举办一场聚会。这涉及到将全部的 n 名雇员划分到多个小组中:每名雇员必须恰好属于一个小组原创 2021-04-01 16:52:07 · 151 阅读 · 0 评论 -
POJ1611 戴好口罩 并查集之路径压缩的妙用 禁止过度复杂思考!
题目如果一个感染者走入一个群体,那么这个群体需要被隔离!小A同学被确诊为新冠感染,并且没有戴口罩!危!时间紧迫!需要尽快找到所有和小A同学直接或者间接接触过的同学,将他们隔离,防止更大范围的扩散.众所周知,学生的交际可能是分小团体的,一位学生可能同时参与多个小团体内.多组数据,对于每组测试数据:第一行为两个整数n和m(n=0表示输入结束,不需要处理),n是学生的数量,m是学生群体的数量。0<n<=3e4,0<=m<=5e2学生编号为0~n-1小A编号为0随后,m原创 2021-03-30 23:29:50 · 104 阅读 · 0 评论