zoukankan      html  css  js  c++  java
  • [小米] 并查集

    题目描写叙述:
    假如已知有n个人和m对好友关系(存于数字r)。假设两个人是直接或间接的好友(好友的好友的好友…)。则觉得他们属于同一个朋友圈,请敲代码求出这n个人里一共同拥有多少个朋友圈。
    假如:n = 5 。 m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人。1和2是好友,2和3是好友,4和5是好友。则1、2、3属于一个朋友圈,4、5属于还有一个朋友圈,结果为2个朋友圈。

    输入:
    输入包括多个測试用例。每一个測试用例的第一行包括两个正整数 n、m。1=<n,m<=100000

    接下来有m行。每行分别输入两个人的编号f,t(1=<f,t<=n),表示f和t是好友。 当n为0时,输入结束,该用例不被处理。

    输出:
    相应每一个測试用例,输出在这n个人里一共同拥有多少个朋友圈。

    例子输入:
    5 3
    1 2
    2 3
    4 5
    3 3
    1 2
    1 3
    2 3
    0
    例子输出:
    2
    1

    解题思路

    使用由多棵树组成的森林来解题。每棵树代表一个朋友圈。构建两个数组id和sz,id[x]表示x的根节点,sz[x]表示以x为根节点的树的结点个数。

    • 初始化:for i = 1 to personCount, id[i] = i, sz[i] = 1;
    • 推断输入的一组关系,看两个结点是否位于同一棵树(根节点是否同样)。假设不同,则将较小的树合并到较大的树(将小数根节点的根节点设为大树的根节点)。同一时候将大树的结点个数设置为大树结点与小树结点之和。
      (对于查找函数。为了加快查询速度,能够对路径进行压缩,即将结点的父节点设置为它的祖父结点)
      更具体思路:http://blog.csdn.net/dm_vincent/article/details/7655764

    实现代码

    #include <iostream>
    using namespace std;
    
    class UF
    {
    public:
        UF(int n)
        {
            id = new int[n];
            sz = new int[n];
            count = n - 1;
            for (int i = 0; i < n; i++)
            {
                id[i] = i;
                sz[i] = 1;
            }
        }
    
        int getCount()
        {
            return count;
        }
    
        int findSet(int n)
        {
            while (n != id[n])
            {
                id[n] = id[id[n]];
                n = id[n];
            }
    
            return n;
        }
    
        void unionSet(int x, int y)
        {
            int dx = findSet(x);
            int dy = findSet(y);
            if (dx != dy)
            {
                count--;
                if (sz[dx] > sz[dy])
                {
                    id[dy] = dx;
                    sz[dx] += sz[dy];
                }
                else
                {
                    id[dx] = dy;
                    sz[dy] += sz[dx];
                }
            }
        }
        ~UF()
        {
            delete [] id;
            delete [] sz;
        }
    private:
        int *id;
        int *sz;
        int count;
    };
    
    
    int main()
    {
        int personCount;
        while (cin>>personCount, personCount)
        {
            UF *uf = new UF(personCount + 1);
            int relationCount;
            cin>>relationCount;
            int x, y;
            for (int i = 0; i < relationCount; i++)
            {
                cin>>x>>y;
                uf->unionSet(x, y);
            }
            cout<<uf->getCount()<<endl;
            delete uf;
        }
        return 0;
    }
  • 相关阅读:
    World Wide Web Publishing Service 服务成功发送一个 停止 控件
    绵竹网站整理
    利用AirPlayer空中播放PC服务器视频、音乐、图片
    ic管理系统
    IIS 6.0下访问aspx文件提示无法找到该页
    GHOST XP SP3无法安装IIS的解决办法
    html 整个页面变灰
    爱普生LQ630K 730K如何换色带
    sql 格式 00123
    serveu 错误1069 由于登陆失败而无法启动服务
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6973020.html
Copyright © 2011-2022 走看看