7-1 并查集【模板】 (30 分)
给出一个并查集,请完成合并和查询操作。
输入格式:
第一行包含两个整数N、M,表示共有N个元素和M个操作。
接下来M行,每行包含三个整数Zi、Xi、Yi。
当Zi=1时,将Xi与Yi所在的集合合并。
当Zi=2时,输出Xi与Yi是否在同一集合内,是的话输出Y;否则的话输出N。
输出格式:
对于每一个Zi=2的操作,对应一行输出,每行包含一个大写字母,为Y或者N。
输入样例:
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4
输出样例:
N
Y
N
Y
数据规模:
对于30%的数据,N<=10,M<=20;
对于70%的数据,N<=100,M<=1000;
对于100%的数据,N<=10000,M<=200000。
递归(超时)
import java.util.Scanner;
public class Main {
static Scanner demo=new Scanner(System.in);
static int[] Arr;
static int find(int A) {//递归
if(A==Arr[A]) {
return A;
}
return A=find(Arr[A]);
}
public static void main(String[] args) {
int X,Y,Z;
int p,q;
int N=demo.nextInt();
int M=demo.nextInt();
Arr=new int[N+1];
for(int i=0;i<N;i++) {
Arr[i]=i;
}
for(int i=0;i<M;i++) {
Z=demo.nextInt();
X=demo.nextInt();
Y=demo.nextInt();
p=find(X);
q=find(Y);
if(Z==2) {
if(p==q) {
System.out.println('Y');
continue;
}
System.out.println('N');
}else {
if(p!=q) {
Arr[p]=q;
}
}
}
}
}
while循环(超时)
import java.util.Scanner;
public class Main{
static int[] Arr;
static int[] size;
static int find(int A) {//while循环
while(A!=Arr[A]) {
A=Arr[A];
}
return Arr[A];
}
static void union(int p,int q) {
if(p==q) {
return;
}
if(size[p]>size[q]) {
Arr[q]=p;
size[p]+=size[q];
}else{
Arr[p]=q;
size[q]+=size[p];
}
}
public static void main(String[] args) {
Scanner demo=new Scanner(System.in);
int X,Y,Z;
int p,q;
int N=demo.nextInt();
int M=demo.nextInt();
Arr=new int[N+1];
size=new int[N];
for(int i=0;i<N;i++) {
Arr[i]=i;
size[i]=1;
}
for(int i=0;i<M;i++) {
Z=demo.nextInt();
X=demo.nextInt();
Y=demo.nextInt();
p=find(X);
q=find(Y);
if(Z==2) {
if(p==q) {
System.out.println('Y');
continue;
}
System.out.println('N');
}else {
union(p,q);
}
}
}
}