带权并查集(在原始并查集的板子上加上权值即可)HDU3038

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038

题意:两个人做无聊的游戏,给出n段区间的和,然后m组询问,询问时给出某一组区间以及它的和,问有几组询问是错误的(注意一下多组输入)

例如给出区间和[1,4]为20,[3,4]为15,再给出[1,2]为30,显然这个[1,2]的值就有问题,它应该为20-15=5。

带权并查集裸题;(带权并查集就类似于一个前缀和,已知两个相对的信息,从而推出一个绝对的信息)

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxx 1010
#define maxn 200010
int fa[maxn],va[maxn];
int Find(int x)
{
    if(x!=fa[x])
    {
        int t=fa[x];
        fa[x]=Find(fa[x]);
        va[x]+=va[t];
    }
    return fa[x];
}
void Union(int x,int y,int s)
{
    int fx=Find(x);
    int fy=Find(y);
    if(fx!=fy)
    {
        fa[fx]=fy;
        va[fx]=s+va[y]-va[x];
    }
}
int main()
{
    int n,m,ans;
    while(cin>>n>>m)
    {
    ans=0;
    for(int i=0; i<=maxn-10; i++)
         fa[i]=i,va[i]=0;
    int x,y,s;
    while(m--)
    {
        cin>>x>>y>>s;
        x--;
        int fx=Find(x);
        int fy=Find(y);
        if(fx!=fy)
        {
           fa[fx]=fy;
           va[fx]=s+va[y]-va[x];//权值合并
        }
        else
        {
           if(va[x]-va[y]!=s)
                ans++;
        }
    }
    cout<<ans<<endl;
    }
    return 0;}

 

posted on 2020-04-07 16:08  mmn  阅读(116)  评论(0编辑  收藏  举报