目录

AcWing 836. 并查集(数组)

发表于
0 1.6~2.0 分钟 716

先说一下本题思路

  • 1.看清题目,主要有俩个操作,合并和查询 。 总体思路是找到俩个祖宗节点,并且把俩个祖宗节点相连(其实就是改p[a的祖宗]=b的祖宗 比如p[3]=4,p[3]=p[4]=4,他们的祖宗都是4,)

  • 2.合并是在一个数组中,利用下标和他所指向的值,如果他所指向的值一样,那么就是一个集合。用下表来记录具体数据。

  • 3.查询直接查询祖宗节点,很好理解,就是比如说查询x,他就会查询p[x]的值,如果和x不一样,会查询find[p[x]]的值,这里有点绕,x如果和p[x]的值不一样,就查询find(p[x]),一个个找,找到祖宗节点,就是x和p[x]一样的节点,原始节点。

  • 主要操作就是针对于祖宗节点进行的。

  • 题目难点(个人愚见):find函数,寻找祖宗节点的过程,下标和值的用法。

#include <iostream>

using namespace std;

const int N = 100010;

int p[N];
int find(int x)   //找祖宗节点的函数
{
  if(p[x] != x) p[x] = find(p[x]);
  return p[x];
}

bool only(int a,int b)  //判断是否在一个集合
{
  return find(a)==find(b);
}


int main()
{
  int a,b;
  char str,test;
  int n,m;

  scanf("%d%d",&n,&m);
  scanf("%c",&test);  //消除回车

  for(int i = 1;i<=n; i++)
    p[i]=i;

  while(m--)
  {

    scanf("%c %d %d",&str,&a,&b);
    scanf("%c",&test);  //消除回车
    // printf("%c%d%d\n",str,a,b);
    if(str == 'M')
    {
      p[find(a)]=find(b); //合并操作,
    }
    else if(str == 'Q')
    {
      if(only(a,b)) printf("Yes\n");
      else printf("No\n");
    }

  }

  return 0;
}