并查集

来源:互联网 发布:mac软件下载的网站 编辑:程序博客网 时间:2024/05/21 17:59

并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中的这种数据结构叫做并查集。
已知有N个人和m对好友关系,如果这两个人士直接好友或者间接的好友(好友的好友….)则认为他们属于同一个朋友圈,n=5,m=3,r={{1,2},{2,3},{4,5}}求出这n个人里一共有多少个朋友圈。
首先解决这个问题我们需要考虑到它的时间复杂度问题,使用并查集就能很好的解决。

这里写图片描述

#include<iostream>#include<stdlib.h>#include<vector>using namespace std;class UnionSet{public:    UnionSet(int n)    {        v.resize(n+1);        for (int i = 0; i <= n; ++i)        {            v[i] = -1;        }    }    int FindRoot(int x)    {        return v[x];//返回它的根    }    void Merge(int x, int y)    {        int root1 = FindRoot(x);        int root2 = FindRoot(y);        if ((root1 == root2) && root1 == -1)//如果他属于一个单独的集合,不属于别的集合        {            v[y] = x;            v[x] += -1;        }        else if (root1 != root2)//属于别的集合        {            if (root1 > 0)            {                v[y] = v[x];                v[root1] += -1;            }            else            {                v[x] = v[y];                v[root2] += -1;            }        }    }    int Size()    {        return v.size();    }    int  Count()    {        int n = Size();        int count = 0;        for (int i = 0; i < n; ++i)        {            if (v[i] <0)            {                ++count;            }        }        return count-1;    }protected:    vector<int> v;};int friends(int n, int m, int arr[][2]){    UnionSet u(n);    for (int i = 0; i < m; ++i)    {        u.Merge(arr[i][0], arr[i][1]);    }    int count = u.Count();    return count;}int main(){    int arr[][2] = { { 1, 2 }, { 2, 3, }, { 4, 5 }, { 6, 7 } };    cout<<friends(7, 4, arr);    system("pause");    return 0;}
原创粉丝点击