并查集-区间问题
来源:互联网 发布:在淘宝怎么设置优惠券 编辑:程序博客网 时间:2024/06/06 14:27
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038
题目大意:给出许多个区间的和,问你在前面给出的天台见都正确的情况下,当前条件是假的 的条数有多少个
题目分析:一般看到并查集的题目,首先要想到怎么去构造,构造的内容有俩个方面,
一个是树的根节点的合并,一个是单个树的状态压缩。
对于这题,比较经典,我们首先来分析第一个,单个树的状态压缩:
a->b->c->d 首先肯定有个这样的树 那么我们现在要实现find(a)的话就要使得结果达到这样一个效果,那就是 使得这个树只有俩层 ,a->d b->d c->d ,那么对于这个带权并查集怎么实现。我们想到了递归 ,用一个数组来保存当前节点到他的父节点的区间和,那么通常的这个递归算法就是先递归到底 然后再回溯逐层求解的过程,那么我们需要从a先递归到d(这也是并查集板子状态压缩的思路),但是最后我们的数组v[a]保存的就成了a到d的区间和 ,那么这就很简单了,用递归求出前面的区间和[b,d] 然后v[a] = v[a] +v[b] 即可
那么对于第二个 ,根节点的合并怎么处理:
首先 我们又俩颗树 要实现函数add(int a,int b)
那么我们传统的思路就是先找到a和b的根节点 ,即 调用find函数 ,这个函数同时也实现了路径压缩的功能,使得你的俩颗树变成了 a-->ra b-->rb 那么现在有个关系就是你要合并[a,b] 那么我们可以在这俩个图之间画一个循环出来 ,类似于大学物理里面的电势下降相等 即 ra->a ra->rb rb->b a->b 那么这个是合并之后的 ,大家可以自己在纸上画出一个循环的图 那么沿着箭头方向 下降的高度一致 则得到了这个结论:
s[a]+[a,b] ==s[r] + [rb,ra] 于是[rb,ra] 就是我们要唯一更新的那个值因为只有rb的状态变化。所以[rb,ra] = sa-sr+s(a,b)
对于这题,我们还要注意一个问题就是 ,题目给的是闭区间的区间和,那么我们在状态压缩的时候啊,就会使得边界的值发生重复 叠加的情况,那么我们这么优化下这个并查集让 父节点是区间的(左边界-1),子节点是右边界,那么我们在s做+=的时候就不会计算俩次了。(这个思路看上去就是根节点是较小的那个边界 子节点则越来越大)
//想法 :对于并查集 其实质就是一颗树 那么我们在求解的时候 用树的性质去维护就可以了 #include<iostream>using namespace std;#define maxn 200005int pre[maxn];int sn[maxn];//维护一个和 a------aa------aaa (根) void init(){for(int i=0;i<=maxn-1;i++){pre[i]=i;sn[i]=0;}}int find(int x){if(x!=pre[x]){int father = pre[x];pre[x] = find(pre[x]);//找到根节点 一路 sn[x] += sn[father];//}return pre[x];//}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int ans=0;init();for(int i=1;i<=m;i++){int a,b,s;scanf("%d%d%d",&a,&b,&s);a--;// [a,ra]int aa=find(a);int bb=find(b);if(aa!=bb)//如果不是一个集合 合并 {pre[aa]=bb;sn[aa]= sn[b]-sn[a]+s;//俩个区间根的差 a----------ra //sn[a]// s:(b)-------(---rb) //sn[b] sn[b]-sn[a]+s}else//同一个集合 {if(sn[a]-sn[b]!=s)ans++;}}printf("%d\n",ans);}}
- 并查集-区间问题
- 【并查集】Mushroom的区间
- Mushroom的区间 (并查集)
- 并查集问题
- 并查集问题
- 并查集问题
- 并查集问题
- 并查集问题
- 并查集-朋友问题
- [并查集]染色问题
- 【并查集】食物链问题
- 布线问题-并查集
- 并查集 Table问题
- 并查集求解问题
- 5---------并查集问题
- poj 2796 利用并查集维护区间和
- Hotel ----线段树并查集,区间合并
- POJ1456贪心(set或者并查集区间合并)
- java 发带有附件的邮件
- 一个分布式服务器集群架构方案
- wordperss安装(17年8月3日)
- 学习mysql的索引设计原则以及常见索引区别
- Zabbix配置mysql监控
- 并查集-区间问题
- ARP解析MAC地址的过程
- ccui.ScrollView()简单应用实例
- Sudoku
- ThreadLocal实现线程范围的共享变量
- OpenCV (二) 一个linux系统下的OpenCV安装配置及编程模板(提供下载链接)
- python 语言使用心得
- hdu 6048 逆序数+思维数学
- 关于matlab中的gcf,gca