• 并查集的两种实现(按秩合并+路径压缩)


    并查集:就是有求并集,查找元素属于哪个集合的功能。

    1、路径压缩:使X到根上的每一个节点的父节点都变为根节点。

    查询:

    void Find(int x)
    {
        if(a[x]==0) return x;
        else return a[x]=Find(a[x]);
    }

    合并:

    void Merge(int x,int y)
    {
        int t1=Find(x),t2=Find(y);
        if(t1!=t2) a[t1]=t2;
    }

    2、按秩合并:使较浅的树成为较深的树的子树。

    查询:

    void Find(int x)
    {
        if(a[x]==0) return x;
        else return a[x]=Find(a[x]);
    }

    合并:

    void Merge(int x,int y)
    {
        int t1=Find(x),t2=Find(y);
        if(t1!=t2){
            if(rank[t1]<=rank[t2]) a[t1]=t2,rank[t2]=max(rank[t2],rank[t1]+1);
            else a[t2]=t1,rank[t1]=max(rank[t1],rank[t2]+1);
        }
    }

    例题:hdu1232

    解法一:路径压缩

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1200;
    int fa[maxn];
    int f(int x)
    {
        if(fa[x]==0) return x;
        else return fa[x]=f(fa[x]);
    }
    int main(void)
    {
        int n,m,t1,t2,i,x,y;
        while(~scanf("%d",&n)&&n){
            scanf("%d",&m);
            memset(fa,0,sizeof(fa));
            while(m--){
                scanf("%d%d",&x,&y);
                t1=f(x),t2=f(y);
                if(t1!=t2) fa[t1]=t2;
            }
            int cnt=0;
            for(i=1;i<=n;i++){
                if(fa[i]==0) cnt++;
            }
            printf("%d
    ",cnt-1);
        }
        return 0;
    }
    View Code

    解法二:按秩求和

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1200;
    int fa[maxn],rk[maxn];
    int f(int x){
        if(fa[x]==0) return x;
        else return fa[x]=f(fa[x]);
    }
    int MAX(int x,int y)
    {
        return x>y?x:y;
    }
    int main(void)
    {
        int n,m,x,y,t1,t2,i;
        while(~scanf("%d",&n)&&n){
            scanf("%d",&m);
            memset(fa,0,sizeof(fa));
            memset(rk,0,sizeof(rk));
            while(m--){
                scanf("%d%d",&x,&y);
                t1=f(x),t2=f(y);
                if(t1!=t2){
                    if(rk[t1]<=rk[t2]) fa[t1]=t2,rk[t1]=MAX(rk[t1],rk[t2]+1);
                    else fa[t2]=t1,rk[t2]=MAX(rk[t2],rk[t1]+1);
                }
            }
            int cnt=0;
            for(i=1;i<=n;i++)
            if(fa[i]==0) cnt++;
            printf("%d
    ",cnt-1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Elasticsearch集成IKAnalyzer分析器
    Elasticsearch操作Document文档
    ElasticSearch简介
    Lucene查询索引
    Lucene索引维护(添加、修改、删除)
    Lucene使用IKAnalyzer分词
    Lucene搜索引擎入门
    MySQL优化(四)——读写分离
    MySQL优化(三)——主从复制
    Java 身份证验证工具类代码模板
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10349837.html
Copyright © 2020-2023  润新知