zoukankan      html  css  js  c++  java
  • 种类并查集——带权并查集——POJ1182;HDU3038

    POJ1182

    HDU3038

    这两个题比较像(一类题目),属于带权(种类)并查集

    poj1182描绘得三种动物种类的关系,按照他一开始给你的关系,优化你的种类关系网络,最后看看再优化的过程中有几处矛盾

    #include <iostream>
    #include <string.h>
    #include <cstdio>
    using namespace std;
    const int maxn = 5e4 + 5e2;
    int pre[maxn],rel[maxn];
    int N,K,ans;
    

     带权并查集,rel就是存储得权值,表示得时当前动物和根动物得关系

    void init()
    {
        for(int i = 0;i <= N;i++)
        {
            pre[i] = i;
            rel[i] = 0;
        }
        ans = 0;
    }
    

     这一步时初始化处理

    int Find(int x)
    {
        if(x != pre[x])
        {
            int tem = pre[x];
            pre[x] = Find(tem);
            rel[x] = (rel[x] + rel[tem] ) % 3;
        }
        return pre[x];
    }
    

     按照向量得计算,在路径压缩得时候(递归)进行权值(关系)得更新

    void join(int a,int b,int r)
    {
        int ra = Find(a);
        int rb = Find(b);
        if(ra == rb)
        {
            if((rel[a] - rel[b] + 3) % 3 != r)ans++;
        }
        else
        {
            pre[ra] = rb;
            rel[ra] = (r - rel[a] + rel[b] + 3) % 3;
        }
    }
    

     如果对于两个给出得关系,他们已经时一个集合得时候,就可以进行谎话得判断,否则呢,连接老大(未出现的,默认为真),新增权值更新;之后呢,这个结点中所有权值得更新都会放在find函数中进行路径压缩得时候进行实现

    #include <iostream>
    #include <string.h>
    #include <cstdio>
    using namespace std;
    const int maxn = 5e4 + 5e2;
    int pre[maxn],rel[maxn];
    int N,K,ans;
    void init()
    {
        for(int i = 0;i <= N;i++)
        {
            pre[i] = i;
            rel[i] = 0;
        }
        ans = 0;
    }
    int Find(int x)
    {
        if(x != pre[x])
        {
            int tem = pre[x];
            pre[x] = Find(tem);
            rel[x] = (rel[x] + rel[tem] ) % 3;
        }
        return pre[x];
    }
    void join(int a,int b,int r)
    {
        int ra = Find(a);
        int rb = Find(b);
        if(ra == rb)
        {
            if((rel[a] - rel[b] + 3) % 3 != r)ans++;
        }
        else
        {
            pre[ra] = rb;
            rel[ra] = (r - rel[a] + rel[b] + 3) % 3;
        }
    }
    int main()
    {
        scanf("%d%d",&N,&K);
    
            init();
            int a,b,r;
            while(K--)
            {
                scanf("%d%d%d",&r,&a,&b);
                if((a == b && r == 2) || a > N || b > N)
                {
                    ans++;
                    continue;
                }
                r--;
                join(a,b,r);
            }
            printf("%d
    ",ans);
    
        return 0;
    }
    

    其实这个题比POJ1182难

    poj1182,比较明显,权值得意义就是区间长度,问你有几处错误为了使得给出得区间能覆盖,所以可以让左端点--,或者右端点++,其他的真的差不多

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    const int maxn = 2e5 + 2e3;
    int pre[maxn],ans[maxn];
    int N,M,ret;
    void init()
    {
        for(int i = 1;i <= N + 1;i++)
        {
            pre[i] = i;
            ans[i] = 0;
        }
        ret = 0;
    }
    int Find(int x)
    {
        if(x != pre[x])
        {
            int tem = pre[x];
            pre[x] = Find(tem);
            ans[x] += ans[tem];
        }
        return pre[x];
    }
    void join(int a,int b,int x)
    {
        int ra = Find(a);
        int rb = Find(b);
        if(ra == rb)
        {
            if(ans[a] - ans[b] != x)ret++;
        }
        else
        {
            pre[ra] = rb;
            ans[ra] = x + ans[b] - ans[a];
        }
    }
    int main()
    {
        while(~scanf("%d%d",&N,&M))
        {
            init();
            int a,b,x;
            while(M--)
            {
                scanf("%d%d%d",&a,&b,&x);
                b++;//防止使得边界重合,易于去判断错误
                join(a,b,x);
            }
            printf("%d
    ",ret);
        }
        return 0;
    }
    
  • 相关阅读:
    星力九代 命中算法源代码 特殊用户处理 点控调整
    Navicat for PostgreSQL 必须知道的十大功能
    如何在某个按钮上触发 bootstarp Modal 组件
    yii2.0 DetailView 自定义样式
    Jquery 利用单个复选款(checkbox)实现全选、反选
    【转载】CentOS LVM磁盘扩容
    VMware ESXi CentOS Linux虚拟机安装VMware Tools教
    Shell 脚本编程
    powershell学习
    Ruby应用记录:修改文件中某个字符串
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/8619682.html
Copyright © 2011-2022 走看看