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

素颜马尾好姑娘i 2022-03-02 11:18 234阅读 0赞

[3038.How Many Answers Are Wrong)(http://acm.hdu.edu.cn/showproblem.php?pid=3038)

题目大意

这题大概意思就是,通过前面所给区间的和,推算所给下一个区间的和的正确与否。

Input

Line 1: Two integers, N and M (1 <= N <= 200000, 1 <= M <= 40000). Means TT wrote N integers and FF asked her M questions.

Line 2…M+1: Line i+1 contains three integer: Ai, Bi and Si. Means TT answered FF that the sum from Ai to Bi is Si. It’s guaranteed that 0 < Ai <= Bi <= N.

You can assume that any sum of subsequence is fit in 32-bit integer.

Output

A single line with a integer denotes how many answers are wrong.

Sample Input

  1. 10 5
  2. 1 10 100
  3. 7 10 28
  4. 1 3 32
  5. 4 6 41
  6. 6 6 1

Sample Output

  1. 1

带权并查集

  1. #include<cstdio>
  2. #include<cstring>
  3. const int maxn = 200000+5;
  4. int fa[maxn];
  5. int sum[maxn]; //表示根结点到子节点的和
  6. int n,m; //n个数,m个问题
  7. int find(int x)
  8. {
  9. if(x!=fa[x])
  10. {
  11. int root=find(fa[x]);
  12. sum[x]+=sum[fa[x]]; //权值合并
  13. fa[x]=root; //路径压缩
  14. }
  15. return fa[x];
  16. }
  17. void init() //初始化
  18. {
  19. for(int i=1;i<=n;i++)
  20. {
  21. fa[i] = i;
  22. }
  23. }
  24. int main()
  25. {
  26. while(~scanf("%d%d",&n,&m))
  27. {
  28. int ans=0;
  29. memset(sum, 0, sizeof(sum));
  30. init();
  31. for(int i=0;i<m;i++)
  32. {
  33. int l,r,d; //l表示左边界,r表示右边界,d表示权值
  34. scanf("%d%d%d",&l,&r,&d);
  35. l--; //左闭右开区间
  36. int fl=find(l);
  37. int fr=find(r);
  38. if(fl!=fr) //该区间未能通过前面所给区间推出来
  39. {
  40. fa[fr]=fl;
  41. sum[fr]=sum[l]-sum[r]+d;
  42. }
  43. else if(sum[r]-sum[l]!=d)
  44. {
  45. ans++;
  46. }
  47. }
  48. printf("%d\n",ans);
  49. }
  50. return 0;
  51. }

发表评论

表情:
评论列表 (有 0 条评论,234人围观)

还没有评论,来说两句吧...

相关阅读