求朋友圈的個數---並查集

問題:
1、已知,有n個人和m對好友關係(存於一個集合r中)
2、如果兩個人是直接的或者間接的好友,(那麼他們的朋友圈可以合併)

則以下爲例:

int a[][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } };

1)有5個人開闢6個整型數組,並初始化爲-1


2)合併同一個朋友圈的人

{1,2}的領導人是1,{2,3}的領導人是2,要將同一個朋友圈的人都合併到領導人下


3.遍歷數組,則遍歷到的負數的個數就是朋友圈的個數,但要除去0號位置的-1。

代碼如下;

#include<vector>

class UnionSet
{
public:
	UnionSet(size_t N)
	{
		//有5個人開闢6個整型數組,並初始化爲-1
		_sets.resize(N+1,-1);
	}
	int FindRoot(int x)
	{
		while (_sets[x] >= 0)//找到對應朋友
		{
			x -= _sets[x];
		}
		return x;
	}
	//合併同一個朋友圈的人
	void UnionFriends(int x1,int x2)	
	{
		int root1 = FindRoot(x1);
		int root2 = FindRoot(x2);
		if (root1 != root2)
		{
			_sets[root1] += _sets[root2];
			_sets[root2] = root1;
		}
	}
	int Friends(int n, int m, int r[][2])
	{
		int counts = 0;
		for (int i = 0; i < m; i++)
		{
			UnionFriends(r[i][0],r[i][1]);
		}
		//計算朋友圈的個數
		for (int i = 1; i < n + 1; i++)//注意我是從1開始遍歷,如果從0開始,就要減掉1
		{
			if (_sets[i] < 0)
				counts++;
		}
		return counts;
	}
protected:
	vector<int> _sets;
};
void test()
{
	int a[][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } };
	int n = 5, m = 3;
	UnionSet u(n);
	cout<<u.Friends(n,m,a)<<endl;
}
哈哈完了!!!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章