您的位置:首页 > 其它

HDU-3038 How Many Answers Are Wrong

2016-07-12 14:52 316 查看
题目链接http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66964#problem/D

题目大意:给你M个区间和,问你有几个是与前面矛盾的。

解题思路:这个题乍一看可能要线段树或树状数组,其实没有必要,区间和可以理解为前缀和相减。每个节点记录前缀和,对每个询问先判断两个节点是否连通,这便是带权并查集干的事了,若联通则权值相减看是否为给定值,若不为则矛盾;若不联通则两棵树合并为一棵(注意有顺序)同时计算出新的子节点的权值。

本题还需注意:题上没说有多组数据但我没用while(scanf()!=EOF)就是wa,看了别人的才知道多组,在这提醒一下。

代码:#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=200005;
int fa[maxn],val[maxn];
int n,m;
int find(int x){
if(fa[x]==x) return x;
else{
int root=find(fa[x]);
val[x]+=val[fa[x]];
return fa[x]=root;
}
}
int ans;
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;i++) {
fa[i]=i;val[i]=0;
}
ans=0;
for(int i=1;i<=m;i++){
int ai,bi,si;
scanf("%d%d%d",&ai,&bi,&si);
ai--;
int r1=find(ai);
int r2=find(bi);
if(r1!=r2){
fa[r2]=r1;
val[r2]=val[ai]+si-val[bi];
}
else if(val[bi]-val[ai]!=si) ans++;
}
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: