zoukankan      html  css  js  c++  java
  • 【带权并查集】How Many Answers Are Wrong HDU

    How Many Answers Are Wrong HDU - 3038

    题意:

    有一个长度已知的整数串,给出一系列包含(l,r)的语句,表示([l,r])这个区间的和。问有多少条语句是错误的。

    思路:

    多组输入!!!

    数据只有(2×10^5)这么大,不用离散化了。

    因为和这题差不多,所以就只简单地写一下关键点。

    • 区间处理

      为了能够连通,给出的闭区间([u,v])要改成((u-1,v])

    • 路径压缩的关系维护:

      假设已知03的和以及35的和,两个加起来就是0~5的和

    [S_{(u,root[u] ]}=S_{(u,fa[u]]}+S_{(fa[u],root[u]]}​ ]

    • 合并时的关系维护:

      假设已知03的和、47的和、04的和,求37的和。嗯,小学数学题。

      [S_{(root(u),root(v)]} = S_{(u,v]} + S_{(v,root(v)]} - S_{(u,root(u)]} ]

    • 查询时的关系计算:

      做题的时候这里没想清楚就写上去了导致没有1A……唉

      计算的前提是两端点的根节点相同,也就是说,分别以这两个端点为左端点的两个区间有相同的右端点,所以:

      [S_{(u,v]}=S_{(u,root]}-S_{(v,root]} ]

      然后将这个结果与给出的和比较是否相同就行了。

    完整代码:

    int n, m;
    int rela[maxn], fa[maxn];
    
    int find(int x) {
        if (fa[x] == -1) return x;
        int tmp = find(fa[x]);
        rela[x] = rela[x] + rela[fa[x]];
        return fa[x] = tmp;
    }
    
    bool merge(int u, int v, int s) {
        int r1 = find(u);
        int r2 = find(v);
        if (r1 == r2) {
            return s == rela[u] - rela[v];
        }
        else {
            fa[r1] = r2;
            rela[r1] = s + rela[v] - rela[u];
            //已知(0,3]为4,(5,7]为8,又(1,5]为7,则(3,7]为7+8-4=11
            return true;
        }
    }
    
    int main()
    {
        //ios::sync_with_stdio(false);
        while (cin >> n >> m) {
            int ans = 0;
            memset(rela, 0, sizeof(rela));
            for (int i = 0; i <= n; i++) fa[i] = -1;
          //注意0也要初始化
            for (int i = 1; i <= m; i++) {
                int u, v, s;
                cin >> u >> v >> s;
                if (u > v) swap(u, v);
                if (!merge(u - 1, v, s)) ans++;
            }
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    Linux中/etc目录下passwd和shadow文件
    Linux基本命令
    Linux目录结构说明与基本操作
    如何用虚拟机VMware Workstation安装CentOs-7
    VPP源码分析及流程图
    VPP环境搭建及配置
    【转】智能指针的交叉引用问题及解决方法
    二叉树的前 中 后 层序遍历
    排序算法
    C和C++的一些区别
  • 原文地址:https://www.cnblogs.com/streamazure/p/13467202.html
Copyright © 2011-2022 走看看