算法1:
注意:
① p[x] 可以看成是链表的next指针,其指向父节点。根节点的next指针指向自己,即p[x] = x;
② x看成是当前节点,p[x] 即是当前节点的父节点,也是当前节点的next指针。
③ 如果当前节点不是根,那么找父节点(p[x] 指向当前节点的父节点)的next指针。并更新当前节点的next指针。
即p[x] = find(p[x]);
// 完整代码
import java.util.*;
public class Main{
static int n, m;
static int N = 100010;
static int[] p = new int[N];
public static int find(int x){
// p[x] 可以看成是链表的next指针,其指向父节点,如果当前节点不是根,那么找父节点的next指针。并更新本节点的next指针
if(p[x] != x) p[x] = find(p[x]);
// 没有优化的代码:超时
// if(p[x] != x) return find(p[x]);
// 上一个if语句中,如果找到当前集合的根,那么p[x]就会更新,那么返回p[x]而不是返回x。
return p[x];
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for(int i = 0; i < n; i ++) p[i] = i;
String opt;
int a, b;
while(m -- > 0){
opt = sc.next();
a = sc.nextInt();
b = sc.nextInt();
if(opt.equals("M")){
p[find(a)] = find(b);
}
else{
System.out.println(find(a) == find(b) ? "Yes" :"No");
}
}
}
}