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

http://acm.hdu.edu.cn/showproblem.php?pid=3038

题意:
给出一个区间1~n,有多次询问,每次回答[l,r]这个区间内的数值和,问在这几次询问中有多少次回答是错误的。

 

思路:
如果[l,r]之间的和为sum,这也就是说r-(l-1)=sum。那么用个数组val[x]维护x到其父亲结点的差值。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn = 200000+5;
16 
17 int n, m;
18 int p[maxn], val[maxn];
19 
20 int finds(int x)
21 {
22     if(p[x]==x)  return x;
23     int tmp=p[x];
24     p[x]=finds(p[x]);
25     val[x]+=val[tmp];
26     return p[x];
27 }
28 
29 int main()
30 {
31    //freopen("in.txt","r",stdin);
32    while(~scanf("%d%d",&n,&m))
33    {
34        int ans = 0;
35        memset(val,0,sizeof(val));
36        for(int i=0;i<=n;i++)  p[i]=i;
37        while(m--)
38        {
39            int a,b,c;
40            scanf("%d%d%d",&a,&b,&c);
41            a--;
42            int x = finds(a);
43            int y = finds(b);
44            if(x != y)
45            {
46                p[x] = y;
47                val[x] = val[b] - val[a] + c;
48            }
49            else
50            {
51                if(abs(val[b]-val[a])!=c)  ans++;
52            }
53        }
54        printf("%d\n",ans);
55    }
56    return 0;
57 }

 

posted @ 2017-11-08 20:48  Kayden_Cheung  阅读(155)  评论(0编辑  收藏  举报
//目录