HDU-3038 How Many Answers Are Wrong(带权并查集)
题意:
给出一个区间的长度 n n n,以及 m m m个子区间的和,如何一个子区间的和与前面的子区间和发生冲突,那么这个子区间和就是错误的,求总错误个数。
题解:
带权并查集裸题,第一次学。
先来看看什么情况下是具有矛盾的:

可以发现,假如说确定了区间 ( 1 , 3 ] (1,3] (1,3]的和, ( 2 , 3 ] (2,3] (2,3]的和,那么就可以判断 ( 1 , 2 ] (1,2] (1,2]的和。还有一种情况,假如确定了区间 ( 1 , 2 ] ( 1,2] (1,2]和区间 ( 2 , 3 ] (2,3] (2,3],那么也可以判断区间 ( 1 , 3 ] (1,3] (1,3]。还要一个问题,我写的左区间都是开的,因为如果都是闭区间,那么端点值就会算上去,那么就会导致计算错误,所以要变成开区间,比如给出区间 [ x , y ] [x,y] [x,y]的和,那么就连接点 x − 1 x-1 x−1到 y y y。
那么怎么实现带权并查集呢?
和普通并查集一样,只不过要额外加一个代表权值的数组 v i s vis vis, v i s [ u ] vis[u] vis[u]表示点 u u u与其父亲节点的权值,如上图, v i s [ 1 ] = 30 vis[1]=30 vis[1]=30。
合并则需要将 v i s vis vis数组的值改变,类似于前缀和的思想:

其他都跟普通并查集一样, f i n d find find函数里也要更新 v i s vis vis数组的值: v i s [ u ] + = v i s [ f a t h e r ] vis[u]+=vis[father] vis[u]+=vis[father]
代码:
#pragma GCC diagnostic error "-std=c++11"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
int fa[MAXN];
int vis[MAXN];
int finder(int x)
{
    if(fa[x]!=x)
    {
        int t=fa[x];
        fa[x]=finder(t);
        vis[x]+=vis[t];
    }
    return fa[x];
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<=n;i++) fa[i]=i,vis[i]=0;
        int ans=0;
        while(m--)
        {
            int l,r,sum;
            scanf("%d%d%d",&l,&r,&sum);
            l--;
            if(l<0||l>n-1||r<1||r>n)
            {
                ans++;
                continue;
            }
            int u=finder(l);
            int v=finder(r);
            if(u==v)
            {
                if(vis[l]!=sum+vis[r])
                {
                    ans++;
                }
            }
            else
            {
                fa[u]=v;
                vis[u]=sum+vis[r]-vis[l];
            }
        }
        printf("%d\n",ans);
    }
}

 
                
             浙公网安备 33010602011771号
浙公网安备 33010602011771号