C++ 求朋友圈的个数 并查集方法

有N个同学,他们之间有些是朋友,有些不是。“友谊”是可以传递的,例如A和B是朋友,B和C是朋友,那么A与C也是朋友;朋友圈就是完成“友谊”传递后的一组朋友。给定N*N的矩阵代表同学间是否是朋友,如果M[i][j]=1代表第i个学生与第j个学生是朋友,否则不是。求朋友圈的个数。
例如:
Input:
[[1,1,0],
[1,1,0],
[0,0,1]]
Output:2

Input:
[[1,1,0],
[1,1,1],
[0,1,1]]
Output:1

#include<vector>
class DisjointSet
{
public:
 int _count;
 DisjointSet(int n)
 {
  for (int i = 0; i < n; i++)
  {
   _id.push_back(i);
   _size.push_back(1);
  }
  _count = n;
 }
 ~DisjointSet() {}
 int find(int p)
 {
  while (p != _id[p])
  {
   _id[p] = _id[_id[p]];
   p = _id[p];
  }
  return p;
 }
 void union_(int p, int q)
 {
  int i = find(p);
  int j = find(q);
  if (i == j)
  {
   return;
  }
  if (_size[i] < _size[j])
  {
   _id[i] = j;
   _size[j] += _size[i];
  }
  else
  {
   _id[j] = i;
   _size[i] += _size[j];
  }
  _count--;
 }
private:
 std::vector<int> _id;
 std::vector<int> _size;
};
class Solution
{
public:
 Solution() {}
 ~Solution() {}
 int findCircleNum(std::vector<std::vector<int>>& M)
 {
  DisjointSet disjoint_set(M.size());
  for (int i = 0; i < M.size(); i++)
  {
   for (int j = i+1; j < M.size(); j++)
   {
    if (M[i][j])
    {
     disjoint_set.union_(i, j);
    }
   }
  }
  return disjoint_set._count;
 }
};
int main()
{
 int test[][3] = { {1,1,0},{1,1,0},{0,0,1} };
 std::vector<std::vector<int>> M(3, std::vector<int>(3, 0));
 for (int i = 0; i < 3; i++)
 {
  for (int j = 0; j < 3; j++)
  {
   M[i][j] = test[i][j];
  }
 }
 Solution solve;
 printf("%d\n", solve.findCircleNum(M));
 return 0;
}

运行结果:

2
发布了135 篇原创文章 · 获赞 121 · 访问量 4884

猜你喜欢

转载自blog.csdn.net/weixin_44208324/article/details/105196597