您的位置:首页 > 其它

用并查集求朋友圈数目

2016-11-12 15:16 239 查看
小米的一道面试题:

假如已知有n个人和m对好友关系,如果两个人是直接或者间接有好友关系,则认为他们属于同一个朋友圈。写程序判断里面有多少朋友圈。

例如:

n = 5, m = 3  r = {(1,2), (2, 3), (4, 5)}  1 2 3 是一个朋友圈, 4 5 是一个朋友圈。

所以输出是2

这道题用并查集来求解就非常容易了。关于并查集的内容,这篇文章写得非常好:

http://blog.csdn.net/dm_vincent/article/details/7655764#reply

根据这篇文章,写了一个求解方法,代码如下:

[cpp] view
plain copy

class UnionFind {  

public:  

    UnionFind(int n) : cnt(n)  

    {  

        id = new int
;  

        for (int i = 0; i < n; i++)  

            id[i] = i;  

  

        size = new int
;  

        for (int i = 0; i < n; i++)  

            size[i] = 1;  

    }  

      

    ~UnionFind()  

    {  

        delete[] id;  

        delete[] size;  

    }  

  

    // 返回连通组的个数  

    int count()  

    {  

        return cnt;  

    }  

  

    // 查找一个节点属于哪个组  

    int findSet(int a)  

    {  

        if (id[a] == a)  

            return a;  

        else  

            return id[a] = findSet(id[a]);  // 查找的同时提高节点的高度  

    }  

  

    bool isSameSet(int a, int b)  

    {  

        int x = findSet(a); // 查找a的组号  

        int y = findSet(b); // 查找b的组号  

  

        return x == y;      // 判断组号是否相同  

    }  

  

    void Union(int a, int b)  

    {  

        int x = findSet(a);  

        int y = findSet(b);  

  

        if (x != y)  

        {  

            if (size[x] < size[y])  

            {  

                id[x] = y;  

                size[y] += size[x];  

            }  

            else  

            {  

                id[y] = x;  

                size[x] += size[y];  

            }  

  

            cnt--;  // 合并后组的数量-1  

        }  

    }  

  

private:  

    int *id;  

    int *size;  

    int cnt;  

};  

  

int main()  

{  

    UnionFind friends(5);  

  

    friends.Union(0, 1);  

    friends.Union(1, 2);  

    friends.Union(3, 4);  

  

    cout << "朋友圈数目:" << friends.count() << endl;  

  

    system("pause");  

    return 0;  

}  

运行结果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: