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

38 篇文章 0 订阅

Description
A有一个由n个数组成的序列,B问A一系列问题A回答,每次B询问区间[a,b]中所有数之和,A的可能说真话也可能说假话,此处认为如果未出现冲突则A说的是真话,共m次询问,问A说假话的次数
Input
第一行为两个整数n和m分别表示序列长度和询问次数,之后m行每行三个整数a,b,s表示[a,b]中所有数之和为s(1<=n<=200000,1<=m<=40000,1<=a<=b<=n,所有数据在int范围内)
Output
输出假话数量
Sample Input
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
Sample Output
1
Solution
将[a,b]中所有数之和为s看作是b比a-1大s,问题转化为简单并查集
Code

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 222222
int n,m,a,b,s,fa[maxn],sum[maxn];
void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        fa[i]=i;
        sum[i]=0;
    }
}
int find(int x)
{
    if(fa[x]!=x)
    {
        int temp=fa[x];
        fa[x]=find(temp);
        sum[x]+=sum[temp];
    }
    return fa[x];
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        init(n);
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&s);
            a--;
            int aa=find(a),bb=find(b);
            if(aa==bb)
            {
                if(sum[b]-sum[a]!=s)ans++;
            }
            else
            {
                fa[bb]=aa;
                sum[bb]=sum[a]-sum[b]+s;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值