How Many Answers Are Wrong HDU - 3038 带权并查集 ╮(╯-╰)╭

题意

第一行两个整数n, m; n表示数组长度,一共m组 。之后每行三个整数,a, b, v:表示数组第a个元素到b第个元素的和为v

判断输入的区间有几组是错误的。

思路

看代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=200005;
int pre[maxn];
int sum[maxn];      //表示该点到根节点的距离
int find(int x)
{
    //这个代码的高明之处就在于Find过程中就将所需要的结点进行更新,并且每棵树的高度不会超过2,所以递归深度也很浅

   if(x!=pre[x])
   {
       int t=pre[x];
       //将寻找根途中碰到的所有的结点都直接接到根上,这样可以降低递归深度,
       pre[x]=find(pre[x]);
       sum[x]+=sum[t];    //利用递归函数的特性,更新sum数组
   }
   return pre[x];
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int cnt=0;
        for(int i=0;i<=n;i++)            //初始化
        {
            pre[i]=i;
            sum[i]=0;
        }
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            a--;              //两个闭区间不好处理,转化为左开右闭。半闭半开区间有一个性质,就是 (a,b]+(b,c]=(a,c]。
            int x=find(a);  //a的树根
            int y=find(b);  //b的树根
            if(x==y)
            {
                if((sum[a]-sum[b])!=c)
                    cnt++;
            }
            else
            {
                pre[x]=y;   //将含a的树移到含b的树上
                //a到x的距离为sum[a],b到y的距离为sum[b],a到b的距离为c

                sum[x]=sum[b]+c-sum[a];  //公式看下边连接
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

sum[x] = sum[b] - sum[a] + v 讲解

本文参考博客

    https://blog.csdn.net/XH413235699/article/details/65938095

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值