HDU 3038 How Many Answers Are Wrong(路径压缩并查集)
2014-03-13 13:59
435 查看
HDU 3038 How Many Answers Are Wrong(路径压缩并查集)
http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:
有一个事先已经写好了的由N个整数组成的整数序列(但是你不知道它的内容),现在给出M条语句,形式如下:
X Y V表示第X个数到第Y个数的和为V值。
这M条语句有可能有错误的语句,比如给出了 1 2 10 ,3 4 10 ,又给一句1 4 100 这句明显是错的,所以对于当前语句如果与前面出现的语句冲突,那么该句就是错的且忽略这句继续往下面处理。
最后输出一共有多少条语句错误。
分析:
本题与POJ1733很相似,也是连续区间的并查集问题(但是本题不需要离散化)。
/article/1331301.html
对于所有输入区间u和v,依然把它变成u-1 和v ,表示(u-1,v]这个范围内(第u个数到第v个数)的整数之和为X。
每个数表示并查集的一个节点,并查集节点维护两种信息:
F[i]:表示i节点的父节点编号。
v[i]:表示i节点到i节点父节点之间的的区间(i,F[i]] 半开半闭区间内整数和为v[i]。
对于findset(x)和bind(u,v)操作,直接用路径压缩并查集的方法更新即可。
如果两个点u和v已经在一个连通分量了,我们还给出了他们的和值,那么就通过分量中u与根,v与根的和值来计算出u与v之间的和值,最后与我们给出的他们的和值比较,看是否相同。如果不同,那么就出错。
AC代码:31ms
http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:
有一个事先已经写好了的由N个整数组成的整数序列(但是你不知道它的内容),现在给出M条语句,形式如下:
X Y V表示第X个数到第Y个数的和为V值。
这M条语句有可能有错误的语句,比如给出了 1 2 10 ,3 4 10 ,又给一句1 4 100 这句明显是错的,所以对于当前语句如果与前面出现的语句冲突,那么该句就是错的且忽略这句继续往下面处理。
最后输出一共有多少条语句错误。
分析:
本题与POJ1733很相似,也是连续区间的并查集问题(但是本题不需要离散化)。
/article/1331301.html
对于所有输入区间u和v,依然把它变成u-1 和v ,表示(u-1,v]这个范围内(第u个数到第v个数)的整数之和为X。
每个数表示并查集的一个节点,并查集节点维护两种信息:
F[i]:表示i节点的父节点编号。
v[i]:表示i节点到i节点父节点之间的的区间(i,F[i]] 半开半闭区间内整数和为v[i]。
对于findset(x)和bind(u,v)操作,直接用路径压缩并查集的方法更新即可。
如果两个点u和v已经在一个连通分量了,我们还给出了他们的和值,那么就通过分量中u与根,v与根的和值来计算出u与v之间的和值,最后与我们给出的他们的和值比较,看是否相同。如果不同,那么就出错。
AC代码:31ms
<span style="font-size:18px;">#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=200000; int F[MAXN]; int v[MAXN]; int findset(int i) { if(F[i]==-1)return i; int temp = findset(F[i]); v[i] +=v[F[i]]; return F[i]=temp; } void bind(int i,int j,int sum)//i<j但F[i]和F[j]的相对大小未知,将F[j]和F[i]合并,且将根值大的合并到根值小的里面去 { int fa=findset(i); int fb=findset(j); if(fa!=fb) { if(fa<fb) { F[fb]=fa; v[fb]=abs( v[i]+sum-v[j] ); } else if(fa>fb) { F[fa]=fb; v[fa]=abs( v[i]+sum-v[j] ); } } } int main() { int n,m; while(scanf("%d%d",&n,&m)==2) { int ans=0; memset(F,-1,sizeof(F)); memset(v,0,sizeof(v)); while(m--) { int a,b,sum; scanf("%d%d%d",&a,&b,&sum); a--;//注意 int fa=findset(a); int fb=findset(b); if(fa==fb) { if(abs( v[a]-v[b] )!=sum) ans++; } else if(fa!=fb) { bind(a,b,sum); } } printf("%d\n",ans); } } </span>
相关文章推荐
- Android逆向分析必备网址大全
- 网站站内文章优化要如何做到
- 利用ant和dedex解析classes.dex
- 学习linux入门经典书籍
- objc 消息转发
- JSTL使用方法介绍
- ZOJ 3261 Connections in GalaxyWar(并查集:离线处理)
- 耶稣教的教义禁止人克隆人?医学还是心理
- Solr学习笔记之3、Solr dataimport - 从SQLServer导入数据建立索引
- java scanner 转载
- 存在主义的创客:不是谷歌,是海尔!
- thinkphp表单数组
- 智能电视,谁的电视?谁的智能?
- SharePoint 2013高级搜索
- mongodb中使用数组建立多对多关系
- Android中自定义的加载对话框和加载条
- 三种方式获取比特币
- 一个进程中各线程的堆和栈的关系
- 正则表达式规则
- 黑马程序员--Java基础--09IO(一)