C++实现并查集

来源:互联网 发布:淘宝单品流量怎么看 编辑:程序博客网 时间:2024/06/01 08:47
将N个不同的元素分成一组不相交的集合。
开始时,每个元素就是一个集合,然后按规律将两个集合进行合并。

假如已知有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属于一个另朋友圈,结果为两个朋友圈。

最后请分析所写代码的时间、空间复杂度。  

这个题用利用并查集实现会比较简易和高效!

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<stdlib.h>using namespace std;class UnionFindSet{public:UnionFindSet(size_t size):_array(new int[size]), _size(size){memset(_array, -1, sizeof(int)*_size);}~UnionFindSet(){if (_array != NULL){delete[] _array;}}void Merge(int root1, int root2){while (_array[root2] >= 0){root2 = _array[root2];}while (_array[root1] >= 0){root1 = _array[root1];}_array[root1] += _array[root2];_array[root2] = root1;}int Find(int child){while (_array[child] >= 0){child = _array[child];}return child;}void print(){for (int i = 0; i < _size; ++i){cout << _array[i] << " ";}cout << endl;}int friends(int n, int m, int r[][2]){UnionFindSet uf(n + 1);for (int i = 0; i < m; i++){int first = r[i][0];int second = r[i][1];uf.Merge(first, second);}uf.print();int count = 0;for (int i = 1; i <= n; i++){if (uf._array[i] < 0){count++;}}return count;}private:int*  _array;size_t _size;};void test(){UnionFindSet us(10);us.Merge(0, 6);us.Merge(0, 7);us.Merge(0, 8);us.Merge(1, 4);us.Merge(1, 9);us.Merge(2, 3);us.Merge(2, 5);us.Merge(0, 4);us.print();cout << "4的朋友树的父节点是" << us.Find(4) << endl;int n = 5;int m = 3;int r[][2]= { { 1, 2 }, { 2, 3 }, { 4, 5 } };int Frindcirle = us.friends(n, m, r);cout << Frindcirle << endl;}int main(){test();system("pause");return 0;}



0 0
原创粉丝点击