//并查集 树形的数据结构。主要处理不相交集合的合并和查询
//使用并查集时,每个集合包含一个或多个元素,会选出某个元素作为代表,让这个代表作为树根结点
//我们关心的是:对于给定的元素我们可以快速的找到它所在的集合,以及合并两个集合
//需求:查找和合并是O(1); 关键:压缩路径
//步骤:
//1、建立新的并查集,包含n个单元数的集合
//2、合并集合:根据给出的数据之间的关系,把具有关系的数据集合合并到一个集合中
//3、查找判断:根据给定的元素查找其树根结点就能判断是不是处于同一个集合
#include<stdio.h>
#include<stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
/*
1 2 3 4 5 6
关系 : (4,3) (3,2) (2,1)
查询 :(4,1) (4,6)
*/
int f[10];
//建立新并查集 未建立联系时,自己是自己的树根节点
void initail(int n)
{
for (int i = 1; i <=n; ++i)
{
f[i] = i;
}
}
//查找树根结点
int find(int x)
{
//非递归
while (f[x] != x)
{
f[x] = x;
}
return x;
}
int find1(int x)
{
//递归
if (f[x] != x)
return find1(f[x]);
else
return x;
}
//压缩路径写法 让祖先成为改并查集的父亲 时间复杂度符合O(1)
int find2(int x)
{
if (f[x] != x)
return f[x] = find2(f[x]);
else
return x;
}
//建立联系
void build(int x, int y)
{
int ax = find2(x);
int ay = find2(y);
f[ay] = ax;
/*写成一句
f[find2[x]]=find2(y);
*/
}
int main()
{
int m;//建立关系的对数
int j;//查找关系的对数
int x, y;//两个元素
initail(6);
scanf_s("%d", &m);
for (int i = 1; i <= m; ++i)
{
scanf_s("%d %d", &x, &y);
build(x, y);
}
scanf_s("%d", &j);
for (int i = 1; i <= j; ++i)
{
scanf_s("%d %d", &x, &y);
if (find2(x) == find2(y))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}