• 并查集计数——总结与例题


    比较基础的知识可以看这位大佬的博客 or 这篇博客
    并查集主要有初始化、union、计数等

    const int N = 1008;
    ll fa[N];///存储父亲节点
    ll sum[N];///计数
    ///寻找父亲节点
    ll _Get_fa(int x){
        if(x == fa[x]) return x;
        else return fa[x] = _Get_fa(fa[x]);
    }
    ///初始化:
    void _Init(){
        for(int i=0;i<=N;i++){
            fa[i] = i;
            sum[i] = 1;
        }
    }
    

    其中_Find的时候一种是递归的方法,另一种是非递归的方法(路径压缩)

    //将根节点设置为-1的非递归方法
    int _Find(int x)
    {
        int y = x;
        while(y!= -1)
            y = fa[y];
        return y;
    }
    

    合并的时候

    for(int i=1;i<=m;i++){
        itn a=read,b=read;
        ll fa_a = _Get_fa(a);
        ll fa_b = _Get_fa(b);
        if(fa_a  != fa_b){
            fa[fa_b] = fa_a;///转移
            sum[fa_a] += sum[fa_b];///计数
        }
    }
    

    一个例题:
    Charles and the Corgi Conundrum
    时间限制: 1 Sec 内存限制: 128 MB

    题目描述
    Charles, the Corgi-obsessed programmer, has just found Corgi Heaven! He visits a pond with exactly n dogs in a nearby field, all of which are Corgis. He wishes to take home exactly one Corgi, and as he is not partial to any particular doggo, he selects one at random. However, we all know that Corgis are amazingly energetic and friendly creatures who share inseparable bonds with others of their kind. Thus, upon choosing an initial Corgi, Charles also has to take its friends, and then its friends’ friends, and so on…
    Now given the friendships that all of the Corgis share, Charles wishes to know what the expected number of Corgis that he will take home is if he chooses an initial Corgi at random.

    Given n Corgis and m friendship bonds between them, determine the number of Corgis that Charles can expect to take home, if he picks one Corgi at random.
    输入
    The first line contains a single, positive integer, s, which is the number of distinct scenarios to consider. For each scenario, the first line contains a two integers, n and m (1 ≤ n ≤ 1,000; 0 ≤ m ≤ 1,000), representing the number of Corgis that exist in the pond and the number of friendship bonds, respectively. The following m lines of the scenario will contain friendship bonds, if any, and consist of two integers, u and v (1 ≤ u ≤ n; 1 ≤ v ≤ n), meaning that Corgi number u and Corgi number v are friends.
    输出
    For each scenario, output “Pond #i: x” where i is the number of the pond (in the order of the input, starting with 1) and x is the expected number of Corgis that Charles can expect to take with him for this pond to 3 decimal places and rounded. For example, 12.1713 rounds to 12.171, 12.1715 rounds to 12.172, and 12.1718 rounds to 12.172.
    样例输入

    2 
    4 2 
    1 2 
    3 4 
    10 6 
    1 3 
    3 2 
    7 5 
    10 8 
    4 3 
    9 10
    

    样例输出

    Pond #1: 2.000 
    Pond #2: 3.000
    

    Code :

    const int N = 1008;
    ll fa[N];
    ll sum[N];
    ll _Get_fa(int x){
        if(x == fa[x]) return x;
        else return fa[x] = _Get_fa(fa[x]);
    }
    void _Init(){
        for(int i=0;i<=N;i++){
            fa[i] = i;
            sum[i] = 1;
        }
    }
    int main()
    {
        ///freopen("this.out","w",stdout);
        int T = read;
        int cas = 0;
        while(T --){
            cas ++;
            _Init();
            printf("Pond #%d: ",cas);
            int n=read,m=read;
            for(int i=1;i<=m;i++){
                itn a=read,b=read;
                ll fa_a = _Get_fa(a);
                ll fa_b = _Get_fa(b);
                if(fa_a  != fa_b){
                    fa[fa_b] = fa_a;
                    sum[fa_a] += sum[fa_b];
                    ///sum[fa_b] += sum[fa_a];
                }
            }
            ll ans = 0;
            for(int i=1;i<=n;i++){
                ///ans += sum[i];
                if(_Get_fa(i) == i){
                    ans += sum[i] * sum[i];
                }
            }
            printf("%.3lf
    ",1.0*ans/(1.0 * n));
        }
        return 0;
    }
    
  • 相关阅读:
    kmp 算法
    jdk 和 cglib 的动态代理
    RestTemplate工具类
    bat脚本切换多个工程的分支
    字符串的左旋转
    输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。
    枚举类型在JPA中的使用
    拾遗
    YAML DEMO
    kiali 1.26 anonymous策略修改为token
  • 原文地址:https://www.cnblogs.com/PushyTao/p/14507425.html
Copyright © 2020-2023  润新知