zoukankan      html  css  js  c++  java
  • 并查集

    一.普通并查集

    int find(int x){
        if(f[x]==x)return x;
        return f[x]=find(f[x]);
    }

    二.带权并查集

    int find(int x){
        if(f[x]==x)return x;
        find(f[x]);
        work();//用儿子与爷爷关系和(儿子与父亲关系和父亲与爷爷关系)的关联,更新权值为儿子与爷爷关系
        return f[x]=f[f[x]];
    }

    http://cogs.pro/cogs/problem/problem.php?pid=298

    /******************************************************************
    
                                带权并查集
                                
    Part I - 权值(relation)的确定。
            我们可以用动物之间“相对”的关系来确定一个并查集。
            0 - 这个节点与它的父节点是同类
            1 - 这个节点被它的父节点吃
            2 - 这个节点吃它的父节点。
            第一个数字(下文中,设为d)指定了后面两种动物的关系:
            1 - X与Y同类
            2 - X吃Y
    
    
    Part II - 路径压缩,以及节点间关系确定
        (1)路径压缩节点时的算法
            通过穷举我们可以发现
            f[now]=f[f[now]]
            relation[now]=(relation[now]+relation[f[now]]) % 3
            推理过程 
            父亲是自己 relation[now]=0;0+0=0; 
            父亲不是自己 
    爷爷(可能还是父亲)和 父亲和儿子   儿子与爷爷
            0          0      (i + j)%3 = 0
            0          1      (i + j)%3 = 1
            0          2      (i + j)%3 = 2
            1          0      (i + j)%3 = 1
            1          1      (i + j)%3 = 2
            1          2      (i + j)%3 = 0
            2          0      (i + j)%3 = 2
            2          1      (i + j)%3 = 0
            2          2      (i + j)%3 = 1
            注:要先更新父亲再更新儿子,可以直接跳到根节点
        (2)集合间关系的确定
            relation[find(y)]=(relation[x]-relation[y]+(d-1)+3) % 3;
            证明:
                y与find(x)的关系为w=(relation[x]+(d-1))%3(其中(d-1)为y与x的关系,可以把x当作y的父节点推出来) 
                find(y)与find(x)的关系要用路径压缩算法反着推出来 relation[find(y)]=(w-relation[y]+3)%3 
                
    Part III - 判断
            如果 find(x)==find(y)代表以前确立了关系,(d-1)表示y与x的关系
            relation[y]是y与根关系,(3-relation[x])%3是根与x关系
            如果(relation[y]-relation[x]+3)%3!=d-1则为假话 
    
    ******************************************************************/
    #include<cstdio>
    #define maxn 50000
    int f[maxn],relation[maxn];
    int find(int x){
        if(f[x]==x)return x;
        find(f[x]);
        relation[x]+=relation[f[x]];relation[x]%=3;
        return f[x]=f[f[x]];
    }
    int mo(int x){
        return x>=0?x%3:(x%3)+3;
    }
    int main(){
        freopen("eat.in","r",stdin);
        freopen("eat.out","w",stdout);
        int n,ans=0,k,d,x,y,a,b;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            f[i]=i;
        }
        for(int i=0;i<k;i++){
            scanf("%d%d%d",&d,&x,&y);d--;
            if(x>n||y>n){
                ans++;
                continue;
            }
            a=find(x),b=find(y);
            if(a==b){
                if(mo(relation[y]-relation[x])!=d)ans++;
            }
            else{
                relation[b]=mo(relation[x]-relation[y]+d);
                f[b]=a;
            }
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    布局重用 include merge ViewStub
    AS 常用插件 MD
    AS 2.0新功能 Instant Run
    AS .ignore插件 忽略文件
    AS Gradle构建工具与Android plugin插件【大全】
    如何开通www国际域名个人网站
    倒计时实现方案总结 Timer Handler
    AS 进行单元测试
    RxJava 设计理念 观察者模式 Observable lambdas MD
    retrofit okhttp RxJava bk Gson Lambda 综合示例【配置】
  • 原文地址:https://www.cnblogs.com/bennettz/p/7356959.html
Copyright © 2011-2022 走看看