zoukankan      html  css  js  c++  java
  • hdu 3038(扩展并查集)

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

    题意:给出区间[1,n],下面有m组数据,l r v区间[l,r]之和为v,每输入一组数据,判断此组条件是否与前面冲突 ,最后输出与前面冲突的数据的个数.
    比如 [1 5]区间和为100 然后后面给出区间[1,2]的和为 200 那肯定就是有问题的了。

    极力推荐这位大牛的博客:http://blog.csdn.net/niushuai666/article/details/6981689

    这题让我学到了很多,特别是关于向量偏移,可以直接找到根节点与子节点的关系

    这题我们利用一个sum[]数组保存从某点到其祖先节点距离

    1.从上图我们可以看出,当roota!=rootb时 如果将roota并入rootb,那么是不是 roota->rootb = b->rootb - b->roota

    然后我们可以知道 b->roota = a->roota - a->b

    所以最后可以推出 roota ->rootb = b->rootb + a->b - a->roota

    而roota的根节点是rootb,所以 roota->rootb = sum[roota]

    然后依次推出得到 sum[roota] = -sum[a]+sum[b]+v (这里的a要说明一下由于是区间 [a,b] ,[a,b] = [root,b]-[root,a-1],所以a要减一)

    2.如果roota==rootb 是不是 a和b的根节点已经相同了?所以我们只要验证 a->b是否与题中的长度一致了。

    所以 a->b = a->root - b->root

    然后得到表达式 v = sum[a]-sum[b] (一定要记住这里的sum都是相对于根节点的,sum的更新在路径压缩的时候更新了)

    这样说是不是懂了向量偏移的思想呢??

    下面上代码:

    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int N =200010;
    int father[N];
    int sum[N];  ///记录当前结点到根结点的距离
    
    int _find(int x){
        if(x!=father[x]){
            int t = father[x];
            father[x] = _find(father[x]);
            sum[x]+=sum[t];
        }
        return father[x];
    }
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=0;i<=n;i++){
                father[i] = i;
                sum[i] = 0;
            }
            int ans = 0;
            while(m--){
                int a,b,v;
                scanf("%d%d%d",&a,&b,&v);
                a--;
                int roota = _find(a);
                int rootb = _find(b);
                if(roota==rootb){
                    if(sum[a]-sum[b]!=v) ans++;  ///精华部分1
                }
                else{
                    father[roota] = rootb;
                    sum[roota] = -sum[a]+sum[b]+v; ///精华部分2
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    爱摘苹果的小明
    盗梦空间
    九九乘法表
    谁是最好的Coder
    画图
    黑色帽子
    a letter and a number
    运维开发面试题
    python 守护进程daemon
    kubernets 应用部署
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5327055.html
Copyright © 2011-2022 走看看