第五节并查集引入•在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中
这一类问题近几年来反复出现在信息学的国际国内竞赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往超过了空间的限制,计算机无法承受;即使在空间上能勉强通过,运行的时间复杂度也极高,根本不可能在比赛规定的运行时间内计算出试题需要的结果,只能采用一种特殊数据结构——并查集来描述
引例•【例4-9】、亲戚(relation)•【问题描述】•或许你并不知道,你的某个朋友是你的亲戚
他可能是你的曾祖父的外公的女婿的外甥女的表姐的孙子
如果能得到完整的家谱,判断两个人是否亲戚应该是可行的,但如果两个人的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系实非人力所能及
在这种情况下,最好的帮手就是计算机
为了将问题简化,你将得到一些亲戚关系的信息,如Marry和Tom是亲戚,Tom和Ben是亲戚,等等
从这些信息中,你可以推出Marry和Ben是亲戚
请写一个程序,对于我们的关于亲戚关系的提问,以最快的速度给出答案
•【输入格式】•输入由两部分组成
•第一部分以N,M开始
N为问题涉及的人的个数(1≤N≤20000)
这些人的编号为1,2,3,…,N
下面有M行(1≤M≤1000000),每行有两个数ai,bi,表示已知ai和bi是亲戚
•第二部分以Q开始
以下Q行有Q个询问(1≤Q≤1000000),每行为ci,di,表示询问ci和di是否为亲戚
引例•【输出格式】•对于每个询问ci,di,输出一行:若ci和di为亲戚,则输出“Yes”,否则输出“No”
•【输入样例】•107•24•57•13•89•12•56•23•3•34•710•89•【输出样例】•Yes