• http://acm.hdu.edu.cn/showproblem.php?pid=3038 并查集权值应用


    题意:[1-n]的区间,有m个询问,每个询问表示[e,f]的和是g,问一共有多少组矛盾

    sum[i]表示i到根节点的和,求区间和用sum[f]-sum[e-1];

    为了简化e--;

    因为是并查集  要出来最前面的那个数  

    1.如果共同祖先相同   直接用sum[f]-sum[e]与给的值g相比较

    2.,不是共同祖先包括两种

    这种为y>x   fa[y]=x; 所以 对应sum[y]=sum[e]+g-sum[f];

    还有x>y   让fa[x]=y  所以对应  sum[x]=sum[f]-g-sum[e];

    下面 代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<math.h>
    using namespace std;
    #define ll long long
    #define INF 0x3f3f3f3f
    #define maxn 10005
    #define N 200005
    int fa[N],sum[N];
    int Find(int x)
    {
        if(x!=fa[x])
        {
            int po=fa[x];
            fa[x]=Find(fa[x]);
            sum[x]+=sum[po];
        }
        return fa[x];
    }
    int main()
    {
        int n,m,e,f,g;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=0; i<=n; i++)
            {
                fa[i]=i;
                sum[i]=0;
            }
            int ans=0;
            while(m--)
            {
                scanf("%d%d%d",&e,&f,&g);
                e--;
                int x=Find(e);//查找这个点的父节点
                int y=Find(f);if(x==y)
                {
                    if(sum[f]-sum[e]!=g)
                        ans++;
                }
                else if(x<y)
                {
                    fa[y]=x;
                    sum[y]=g+sum[e]-sum[f];
                }
                else
                {
                    fa[x]=y;
                    sum[x]=sum[f]-g-sum[e];
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    IK 用java 代码实现分词
    杭电2017
    线性表学习
    一个比较有意思的C语言问题
    杭电1020
    python注释
    Java API —— 递归
    Java API —— File类
    Java API —— 异常
    Map集合案例
  • 原文地址:https://www.cnblogs.com/a719525932/p/5989803.html
Copyright © 2020-2023  润新知