• 备战快速复习--day6


    并查集

    里面主要的函数是Union和findfather两个

    Union的注意事项

    • Union只在确定两者原先不需要同一个根,新增加了链接的情况下使用。不然会出现环(一个链条上面的第n个节点连到了头)
    • Union的作用是,发现a和b不一样以后,把a的根节点与b的根节点连在一起。连在一起的是两个的根!(这就会导致,原来一个根是某些点的father,但是现在不是了)
    • 在Union之后会存在一些需要被更新的father,这些点在全部新链接结束以后,通过一轮findfather进行更新就可以。(他们能正确找到自己的组织,但是原来是正确的根,现在不是顶点了,需要更新)
    • 因为在合并的过程中,那时候调用findfather,还是俩根的状态,并不会更新到最优
    • 一定要注意必须大写!U,不然是关键词!

    findfather的注意事项

    • 这个在找完以后,要把路途中的点都更新一下子
    • 更新的过程中要注意保留中间数值,因为a被修改直接使用father[a]显然有问题

    代码过了样例(应该没问题)

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    using namespace std;
    int father[1005];
    bool pd[1005];
    int n,m;
    int findfather(int x)
    {
        int a=x;
        while(x!=father[x])
            x=father[x];
        int z=a;
        while(a!=father[a])
        {
            z=a;
            a=father[a];
            father[z]=x;
        }
        return x;
    }
    void Union(int a,int b)
    {
        if(findfather(a)!=findfather(b))
            father[findfather(a)]=findfather(b);
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        int temp1,temp2;
        int ans=0;
        memset(pd,0,sizeof(pd));
        for(int i=1;i<=n;i++)
            father[i]=i;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&temp1,&temp2);
            Union(temp1,temp2);
        }
        /*for(int i=1;i<=n;i++)
            printf("%d ",father[i]);
        printf("
    ");*/
        for(int i=1;i<=n;i++)
            pd[findfather(i)]=true;
        /*for(int i=1;i<=n;i++)
            printf("%d ",father[i]);
        printf("
    ");*/
        for(int i=1;i<=n;i++)
            if(pd[i]) ans++;
        printf("%d",ans);
        return 0;
    }
    View Code

     PAT A1107

    这道题是给n个人,然后给出每个人喜欢的类别,类别有1000种(大概),把有喜欢同类的人合并在一起,求总共几个类别

    两两合并太麻烦,存一个就行,在全执行结束之后再更新一次father,为了减少运行次数,把所有的father都像hobby的标注对象靠拢,代码如下

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int father[1005];
    int hobby[1005];
    int pd[1005];
    int ans,n;
    bool cmp(int a,int b)
    {
        return a>b;
    }
    int findfather(int x)
    {
        int a=x;
        while(x!=father[x])
        {
            x=father[x];
        }
        while(a!=father[a])
        {
            int z=a;
            a=father[a];
            father[a]=x;
        }
        return x;
    }
    void Union(int a,int b)
    {
        if(findfather(a)!=findfather(b))
            father[findfather(a)]=findfather(b);
    }
    int main()
    {
        scanf("%d",&n);
        int num,temp;
        memset(hobby,0,sizeof(hobby));
        memset(pd,0,sizeof(pd));
        for(int i=1;i<=n;i++)
        {
            father[i]=i;
            scanf("%d: ",&num);
            for(int j=1;j<=num;j++)
            {
                scanf("%d",&temp);
                if(hobby[temp]==0)
                {
                    hobby[temp]=i;
                }
                else
                {
                    Union(i,hobby[temp]);
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            pd[findfather(i)]++;
        }
        sort(pd,pd+1000,cmp);
        while(pd[ans]>0)
        {
            ans++;
        }
        printf("%d
    ",ans);
        for(int i=0;i<=ans-2;i++)
            printf("%d ",pd[i]);
        printf("%d",pd[ans-1]);
        return 0;
    }
    View Code
    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    SQL Server 百万级数据提高查询速度的方法(转)
    sql优化的几种方法
    MyBatis中调用存储过程和函数
    android ipc通信机制之二序列化接口和Binder
    APK的目录结构
    android Handler错误,不同的包Handler
    BaiduMap开发,获取公交站点信息。
    GitHub托管项目步骤
    Mysql,JDBC封装
    简单工厂模式练习
  • 原文地址:https://www.cnblogs.com/tingxilin/p/12348142.html
Copyright © 2020-2023  润新知