zoukankan      html  css  js  c++  java
  • uva 10608 FRIENDS

    纯粹考察并查集,算是一个经典问题;统计一个集合中有多少个元素,然后找到元素个数最多的集合

    就普通的并查集,就能过了

    然后另外写了压缩路径,没想到时间没有改变

    然后再写一个,时间还是没有改变,好吧……………………

    只要懂基本的并查集的话,代码都不成问题,很裸的并查集而已

    代码一:纯粹

    #include <cstdio>
    #include <cstring>
    #define N 30000
    int p[N],c[N];
    int n,m;
    
    int find(int x)
    { return p[x]==x ? x : p[x]=find(p[x]);  }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            { p[i]=i; c[i]=0; }
    
            for(int i=1; i<=m; i++)
            {
                int x,y,u,v;
                scanf("%d%d",&u,&v);
                x=find(u);
                y=find(v);
                if(x!=y)
                    p[x]=y;
            }
    
            for(int i=1; i<=n; i++)  //扫描所有元素找到他们的祖先然后祖先的孩子数计数
            {
                int x=find(i);
                c[x]++;
            }
            int max=0;
            for(int i=1; i<=n; i++)
                if(c[i]>max)
                    max=c[i];
    
            printf("%d\n",max);
        }
        return 0;
    }

    代码二:压缩路径

    #include <cstdio>
    #include <cstring>
    #define N 30000
    int p[N],c[N];
    int n,m;
    
    int find(int x)  //迭代式
    {
        int i=x,r=x,j;
        while(r!=p[r])
            r=p[r];
        while(i!=r)  //路径压缩
        {
            j=p[i];  //先记录下i的双亲
            p[i]=r;  //修改i的双亲直接与祖先相连
            i=j;     //接下来修改原本的双亲
        }
        return r;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            { p[i]=i; c[i]=0; }
    
            for(int i=1; i<=m; i++)
            {
                int x,y,u,v;
                scanf("%d%d",&u,&v);
                x=find(u);
                y=find(v);
                if(x!=y)
                    p[x]=y;
            }
    
            for(int i=1; i<=n; i++)  //扫描所有元素找到他们的祖先然后祖先的孩子数计数
            {
                int x=find(i);
                c[x]++;
            }
            int max=0;
            for(int i=1; i<=n; i++)
                if(c[i]>max)
                    max=c[i];
    
            printf("%d\n",max);
        }
        return 0;
    }

    代码三:再修改一下统计集合元素的方法

    #include <cstdio>
    #include <cstring>
    #define N 30000
    int p[N],c[N];
    int n,m;
    
    int find(int x)  //迭代式
    {
        int i=x,r=x,j;
        while(r!=p[r])
            r=p[r];
        while(i!=r)  //路径压缩
        {
            j=p[i];  //先记录下i的双亲
            p[i]=r;  //修改i的双亲直接与祖先相连
            i=j;     //接下来修改原本的双亲
        }
        return r;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            { p[i]=i; c[i]=1; }
    
            int max=0;
            for(int i=1; i<=m; i++)
            {
                int x,y,u,v;
                scanf("%d%d",&u,&v);
                x=find(u);
                y=find(v);
                if(x!=y)
                {
                    p[x]=y;
                    c[y]+=c[x];
                    if(c[y]>max)
                        max=c[y];
                }
            }
            printf("%d\n",max);
        }
        return 0;
    }

    悲剧,时间没本质提高啊………………………………

  • 相关阅读:
    LeetCode Merge Two Sorted Lists 归并排序
    LeetCode Add Binary 两个二进制数相加
    LeetCode Climbing Stairs 爬楼梯
    034 Search for a Range 搜索范围
    033 Search in Rotated Sorted Array 搜索旋转排序数组
    032 Longest Valid Parentheses 最长有效括号
    031 Next Permutation 下一个排列
    030 Substring with Concatenation of All Words 与所有单词相关联的字串
    029 Divide Two Integers 两数相除
    028 Implement strStr() 实现 strStr()
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2784669.html
Copyright © 2011-2022 走看看