并查集: 查询时间近乎O(1).
1.将两个集合合并.
2.询问两个元素是否在一个集合当中.
基本原理:每个节点存储基本原理:每个集合用一棵树来表示树根的编号就是整个集合的编号.它的父节点,p[x]表示x的父节点
问题1: 如何判断树根: if (p[x] == x);
问题2: 如何求x的集合编号: while (p[x] != x) x = p[x];
问题3: 如何合并两个集合: p 是x的集合编号,py是y的集合编号。p[x] = y;
题解代码
#include <iostream>
using namespace std;
const int N = 100010;
int p[N];
int find(int x)//返回x的祖宗节点 + 路径压缩
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) p[i] = i;//最开始每一个数为一个集合,让自己的根节点为自己
while (m -- )
{
char op[2];
int a, b;
scanf("%s%d%d", op, &a, &b);
if (*op == 'M') {
//if(find(a)!=find(b)) 不用加,如果相等就是自己等于自己
p[find(a)] = find(b);
}
else
{
if (find(a) == find(b)) puts("Yes");
else puts("No");
}
}
return 0;
}