zoukankan      html  css  js  c++  java
  • poj 1611 The Suspects (并查集)

    简单入门并查集, 以前已经做过,但是代码不太好。DP优化搞上火了,做做别的换换脑子...

    以前代码 

    Memory: 356KTime: 32MS
    #include<cstdio>

    usingnamespace std;

    const int maxn = 30000;

    int father[maxn+5];//记录父节点
    int len[maxn+5];//记录以该点为根的集合元素的个数

    void init(int n){//并查集的初始化
        int i;
        for (i=0; i<n; i++)
        {
            father[i] = i;
            len[i] = 1;
        }
    }

    inline int getroot(int x){//获得某节点的根节点(不同于父节点),并压缩路径
        int r = x;
        while(father[r]!=r)
            r = father[r];
        while(father[x]!=r){
            father[x] = r;
            x = father[x];
        }
        return r;
    }

    inline void join(int s, int x){//把s和x合并起来
        int a = getroot(s);
        int b = getroot(x);
        if (a!=b){
            father[a] = b;
            len[b] += len[a];
        }
    }

    int main(){
        int n, m, k;
        int i, j, x, s;
        while(scanf("%d %d", &n, &m)!=EOF){
            if (n==0 && m==0break;
            init(n);
            for (i=0; i<m; i++){
                scanf("%d", &k);
                if (k==0continue;
                scanf("%d", &s);
                for (j=1; j<k; j++){
                    scanf("%d", &x);
                    join(s, x);
                }
            }
            printf("%d\n", len[getroot(0)]);
        }
        return 0;
    }


    不用按秩合并的话

    Memory: 284KTime: 16MS

    #include<cstdio>
    int p[30005] ;
    void make_set(int n){
        for(int i=0; i<n; i++)
            p[i] = i ;
    }
    int find_set(int x){
        if(x!=p[x])
            p[x] = find_set(p[x]) ;
        return p[x] ;
    }
    void union_set(int x, int y){
        x = find_set(x) ;
        y = find_set(y) ;
        if(x!=y)
            p[y] = x ;
    }
    int main(){
        int n, m, i, x, y, sum ;
        while(~scanf("%d%d", &n, &m)&&(n+m)){
            make_set(n) ;
            while(m--){
                scanf("%d", &i) ;
                scanf("%d", &x) ;
                i -- ;
                while(i--){
                    scanf("%d", &y) ;
                    union_set(x, y) ;
                }
            }
            sum = 1 ;
            for(i=1; i<n; i++)
                if(find_set(i)==find_set(0))
                    sum ++ ;
            printf("%d\n", sum) ;
        }
        return 0 ;
    }

    按秩合并 

    Memory: 400KTime: 0MS
    #include<cstdio> 

    int p[30005], r[30005] ;

    void make_set(int n){
        for(int i=0; i<n; i++){
            p[i] = i ;
            r[i] = 0 ;
        }
    }
    int find_set(int x){
        if(x!=p[x])
            p[x] = find_set(p[x]) ;
        return p[x] ;
    }
    void union_set(int x, int y){
        x = find_set(x) ;
        y = find_set(y) ;
        if(x!=y){
            if(r[x]>r[y])
                p[y] = x ;
            else{
                p[x] = y ;
                if(r[x]==r[y])
                    r[y] ++ ;
            }
        }
    }
    int main(){
        int n, m, i, x, y, sum ;
        while(~scanf("%d%d", &n, &m)&&(n+m)){
            make_set(n) ;
            while(m--){
                scanf("%d", &i) ;
                scanf("%d", &x) ;
                i -- ;
                while(i--){
                    scanf("%d", &y) ;
                    union_set(x, y) ;
                }
            }
            sum = 1 ;
            for(i=1; i<n; i++)
                if(find_set(i)==find_set(0))
                    sum ++ ;
            printf("%d\n", sum) ;
        }
        return 0 ;
    }


  • 相关阅读:
    搬家来博客园了
    公司初印象
    毕业之殇觉醒
    毕业之殇天意弄人
    毕业之殇预告篇
    scribe 安装文档
    毕业之殇寻找
    IOS 资料整理(转)
    IOS IPHONE相册应用 资料整理
    NSFileManager和NSFileHandle(附:获取文件大小 )
  • 原文地址:https://www.cnblogs.com/xiaolongchase/p/2332437.html
Copyright © 2011-2022 走看看