HDU 3038 How Many Answers Are Wrong(带权并查集)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1272

题目大意:有n条信息,每条信息都给出区间l到r的值,如果后面出现的信息与前面的矛盾,那么就算是一个错误信息,问一共给出多少错误信息。比如1给出三条信息1 4 10 ,1 2 5,3 4 6那么第三条就错了,因为[1,2]+[3,4]应为[1,4]等于10,而现在是11。

解题思路:对于l~r之间的和是sum,其实可以理解成r比l-1大sum,这样刚好可以跟前面一段区间连起来。再利用val[]记录r比l大的值,就变成常规的带权并查集了。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 typedef long long LL;
 6 const int INF=0x3f3f3f3f;
 7 const int N=2e5+5;
 8 
 9 int root[N],val[N];
10 
11 int find(int x){
12     if(root[x]==x)
13         return x;
14     int tmp=find(root[x]);
15     val[x]+=val[root[x]];
16     return root[x]=tmp;
17 }
18 
19 int main(){
20     int n,m,ans;
21     while(~scanf("%d%d",&n,&m)){
22         ans=0;
23         memset(val,0,sizeof(val));
24         for(int i=0;i<=n;i++){
25             root[i]=i;
26         }
27         while(m--){
28             int l,r,sum;
29             scanf("%d%d%d",&l,&r,&sum);
30             int t1=find(l-1);
31             int t2=find(r);
32             if(t1==t2){
33                 if(sum!=val[r]-val[l-1])
34                     ans++;
35                 continue;
36             }
37             root[t2]=t1;
38             val[t2]=val[l-1]-val[r]+sum;
39         }
40         printf("%d\n",ans);
41     }
42     return 0;
43 }

 

posted @ 2017-10-10 22:12  Yeader  阅读(114)  评论(0编辑  收藏  举报