How Many Answers Are Wrong——带权并查集

题目链接

题意:

有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已经给出的是矛盾的。

例:

【1,5】 = 10 ,【6.10】 = 10, 【1, 10】 = 30,这明显第三个与前面两个矛盾。

题解:

sum【i】 表示 1到i的和 如果存在 【i,a】与【i,b】 则只要判断 【b,i】- 【a-1,i】是否等于 c 即可

所以用并查集维护公共点 即根节点

#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
int f[maxn];
int n,m;
int sum[maxn];///根节点到 i 的距离
int Find(int x)
{
    if(x==f[x])return x;
    int root=Find(f[x]);
    sum[x]+=sum[f[x]];
    return f[x]=root;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<=n;i++)f[i]=i,sum[i]=0;
        int ans=0;
        while(m--)
        {
            int a,b,s;
            scanf("%d%d%d",&a,&b,&s);
            a--;
            int fx=Find(a);
            int fy=Find(b);
            if(fx!=fy)
            {
                f[fy]=fx;
                sum[fy]=sum[a]+s-sum[b];///   sum[b]+sum[fy]-sum[a]=s
            }
            else
            {
                if(sum[b]-sum[a]!=s)ans++;
            }
        }
        printf("%d\n",ans);
    }

    return 0;
} 
View Code

 

posted @ 2019-09-29 21:31  。小姜  阅读(260)  评论(0编辑  收藏  举报