D - How Many Answers Are Wrong HDU - 3038 【关系并查集】

题意:m个区间,及其和。问有几个错误。

思路:sigma[l~r]=sigma[r]-sigma[l-1]。如果l-1和r有相同的最left值,说明它们的差值在之前已经准确的算出来了,只要判断是否和给的sum相同即可。否则之前没准确算出来,就可以把它们合并。合并注意回溯代码顺序问题,一定要返回par[x]


#include <stdio.h>
#include <iostream>

using namespace std;

const int MAXN=200000+5;
int v[MAXN];
int par[MAXN];

int Find(int x)
{
    int temp=par[x]; //保存原父亲的编号
    if(par[x]!=x)
    {
        par[x]=Find(par[x]);
        v[x]+=v[temp]; // 秩最多为3,这是关键。每次Find都会进行路径压缩,然后直接连接到根节点上。
    }
    return par[x]; //return 可以保证秩从3变到2
}

int main(void)
{
    int n,m;
    while((scanf("%d%d",&n,&m))!=EOF)
    {
        for(int i=0; i<=n; i++)
            par[i]=i,v[i]=0;
        int ans=0;
        for(int i=1; i<=m; i++)
        {
            int l,r,sum;
            scanf("%d%d%d",&l,&r,&sum);
            l--;
            int rootl=Find(l),rootr=Find(r);
            if(rootl==rootr)
            {
                if(v[r]-v[l]!=sum)  ans++;
            }
            else if(rootl<rootr)      //向量关系,手动画图
            {
                par[rootr]=rootl;
                v[rootr]=sum+v[l]-v[r];
            }
            else if(rootl>rootr)
            {
                par[rootl]=rootr;
                v[rootl]=-(sum+v[l])+v[r];
            }
        }
        cout << ans << endl;
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值