How Many Answers Are Wrong(带权并查集(裸))
来源:互联网 发布:最早一批网络歌曲 编辑:程序博客网 时间:2024/06/11 02:43
题目来源:https://vjudge.net/problem/HDU-3038
【题意】
给出n,m,下面m行每一行有三个数,a,b,v,v代表的是区间【a,b】的和,每一行都是这样,但是当第i行与前i-1行发生冲突的时候,记录一下。输出共错误多少句。举个例子:第一行是 1 100 200,第二行是1 50 300,这就发生了冲突。
【思路】
http://blog.csdn.net/dextrad_ihacker/article/details/51016017
这个大佬的博客写的很清晰(有配图),很容易理解。以下是我的个人见解(当然,也只是对大佬的话语的重复)。
首先,要理解第i行,a,b,v,假设用dis代表距离,那么dis(a-b)=v;但是前i-1行不一定有一模一样的a,b,v,所以就要借助一个过渡,假设是c,那么就可以这样:dis(a-c)-dis(b-c)=v,有没有发现如果我们把他们共同的根节点也就是祖先,当做c的话,只需要知道节点a到祖先的距离,节点b到祖先的距离,就可以知道a和b的距离了(假设他们有共同的祖先),那如果a和b没有共同的祖先,那么在之前就找不到他们俩的关系,就不能确定dis(a-b)=v这个关系为假。就可以把他们的父节点连在一起,即把他俩各自的祖先弄到一起,比如把a的祖先拿去给b的祖先当父亲。
还有一点,给出的是一个闭区间,【a,b】,但是他可以转化为(a-1,b],左开右闭。半闭半开区间有一个性质,就是 (a,b]+(b,c]=(a,c];
还有一点灰常重要的东西是怎么求a,b之间的距离。
假如一开始没关系,那么用rank数组来表示a,b各自到各自祖先的距离。那么在把a的祖先给b的祖先当父亲之后,那么b到祖先的距离也就是rank【b】就要再加上b原本的祖先到a的祖先的距离,更新一下,其中find函数(找根节点的函数)里rank【x】+=rank【pre【x】】(这里pre数组存的是对应数的父节点)。
【代码】
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#include<map>#include<queue>#include<stack>#include<set>using namespace std;typedef long long LL;int pre[200010],ranks[200010];int find(int root){ if(pre[root]==root)return root; int t=find(pre[root]); ranks[root]+=ranks[pre[root]];//精髓 return pre[root]=t;}int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { int ans=0; for(int i=1; i<=n; i++) pre[i]=i;//把各自的父节点赋给他本身 memset(ranks,0,sizeof(ranks)); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); a--; int fa=find(a); int fb=find(b); if(fa!=fb) { pre[fb]=fa; ranks[fb]=ranks[a]-ranks[b]+c;//更新距离 } else { if(ranks[b]-ranks[a]!=c) ans++; } } printf("%d\n",ans); }}
- How Many Answers Are Wrong(带权并查集(裸))
- 带权并查集 How Many Answers Are Wrong
- HDU 3038 how many answers are wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong (带权并查集+区间判断)
- HDU - 3038 How Many Answers Are Wrong (带权并查集)
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- 杭电3038 How Many Answers Are Wrong(带权并查集-经典)
- 【HDU】How Many Answers Are Wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- hdu 3038 How Many Answers Are Wrong(带权并查集)
- How Many Answers Are Wrong hdu 3038 (带权并查集)
- hdu 3038 How Many Answers Are Wrong (带权并查集入门)
- How Many Answers Are Wrong (带权的并查集)
- How Many Answers Are Wrong(并查集)
- 简单并查集之带权并查集HDU3038 How Many Answers Are Wrong
- 【杭电oj】3038 - How Many Answers Are Wrong(带权并查集,好题)
- HDU 3038 How Many Answers Are Wrong (并查集好题)(带权并查集)
- POJ1573Robot Motion
- SpringBoot 整合SpringMvc 原理探究(DispatchServlet添加流程)
- IOS之OC语言简介
- 01-最长上升子序列
- jquery $(this).attr $(this).val方法使用介绍
- How Many Answers Are Wrong(带权并查集(裸))
- vue引入css,less遇到的坑和解决办法
- shell基础-环境变量配置文件
- tarjan算法模板(强连通分量)
- 动态规划--开餐馆
- Python pass 语句
- vim打开文件时显示行号
- 网络字节序和主机字节序
- base64的算法详解