zoukankan      html  css  js  c++  java
  • 带权并查集 模板 HDU

    https://vjudge.net/problem/HDU-3038

    TT 写一串数字,对 FF 不可见
    FF 选择一个区间(会重复操作), TT 把这个区间的和告诉 FF,然后,一些和是不正确的,所以,有一些答案是矛盾的,根据这些矛盾求出答案错误的个数。
    注意两点:1、TT 给的一个 和 是正确的,如果它与之前给的 和 不矛盾。
    2、FF 发现一个与之前矛盾的 和 之后,该 和 不再参与之后的分析,直接被抛弃了。

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

    博客:https://www.cnblogs.com/liyinggang/p/5327055.html

    https://blog.csdn.net/yjr3426619/article/details/82315133?tdsourcetag=s_pcqq_aiomsg

    首先要先知道带权路径压缩的写法:

    int find(int x){
        if(pre[x]!=x){
            int y = pre[x];
            pre[x] = find(pre[x]);
            sum[x] += sum[y];
        }
        return pre[x];
    }

    还有带权并查集合并:

    pre[fa] = fb;
    sum[fa] = -sum[a] + s + sum[b] ;

    这题我们利用一个sum[]数组保存从某点到其祖先节点距离。
    通过处理,带权并查集每个节点的sum值都是其指向父亲节点的权值
    中间如果经历过了路径压缩,就是指向祖先的权值

    注意,给出区间的 L 和 R可能相同,而就无法用并查集这个数据结构来做了,所以存入时要把 L- - 或者R ++

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <set>
    #include <map>
    #include <stack>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define INF (1<<30)
    using namespace std;
    
    const int maxn = 2e5+7;
    int sum[maxn];
    int pre[maxn];
    
    int find(int x){
        if(pre[x]!=x){
            int y = pre[x];
            pre[x] = find(pre[x]);
            sum[x] += sum[y];
        }
        return pre[x];
    }
    
    int main(){
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=0; i<=n+1; i++){
                pre[i] = i;
                sum[i] = 0;
            }
            int fa,fb,a,b,s,ans=0;
            while(m--){
                scanf("%d%d%d",&a,&b,&s);
                b++;
                fa = find(a);
                fb = find(b);
                if(fa==fb){
                    if(sum[a]!=s+sum[b]){
                        ans++;
                    }
                }
                else{
                    pre[fa] = fb;
                    sum[fa] = -sum[a] + s + sum[b] ;
                }
            }
            printf("%d
    ", ans);
        }
    }
  • 相关阅读:
    Windows程序设计6(内存、线程、进程)
    Windows程序设计5(MDI、库程序、文件)
    Windows程序设计4(文字、对话框、各控件)
    大数据开发学习之构建Hadoop集群-(0)
    杂谈
    Windows程序设计2(消息机制、菜单)
    QT 学习笔记概述(一)
    Linux/Windows 实用工具简记
    读书笔记《深度探索c++对象模型》(0)
    读书笔记《深入理解计算机系统》(第三版) 概述
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11469812.html
Copyright © 2011-2022 走看看