AcWing 836. 合并集合(并查集)

mac2022-06-30  23

昨天写了并查集的LeetCode模板题,今天再练习AcWing的模板题,遇到一点小问题。 题目: 一共有n个数,编号是1~n,最开始每个数各自在一个集合中。

现在要进行m个操作,操作共有两种:

“M a b”,将编号为a和b的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作; “Q a b”,询问编号为a和b的两个数是否在同一个集合中; 输入格式 第一行输入整数n和m。

接下来m行,每行包含一个操作指令,指令为“M a b”或“Q a b”中的一种。

输出格式 对于每个询问指令”Q a b”,都要输出一个结果,如果a和b在同一集合内,则输出“Yes”,否则输出“No”。

每个结果占一行。

数据范围 1≤n,m≤105 输入样例: 4 5 M 1 2 M 3 4 Q 1 2 Q 1 3 Q 3 4 输出样例: Yes No Yes


WA代码,最后一组数据不知道为什么过不去,大神可以帮我看一下:

import java.util.Arrays; import java.util.Scanner; public class Main { static int pre[]; static int n; static int m, a, b; static char hand; static Scanner sn = new Scanner(System.in); public static void main(String[] args) { n = sn.nextInt(); m = sn.nextInt(); pre = new int[n + 1]; Arrays.fill(pre, -1);//如果pre == 1,则这个人就是头儿 pre[0] = 0; //原题从1 ~ n,这里忽略 0 for (int i = 0; i < m; i++) { hand = sn.next().charAt(0); a = sn.nextInt(); b = sn.nextInt(); if (hand == 'M') union(a, b); else { if (find(a) != find(b)) { System.out.println("No"); } else System.out.println("Yes"); } } } public static int find(int b) { if (pre[b] == -1) return b; return find(pre[b]); } private static void union(int a, int b) { int x = find(a); int y = find(b); if (x != y) pre[x] = y; } }

看了题解后稍微改了一下代码 AC代码,感觉没啥差别啊?

import java.util.Arrays; import java.util.Scanner; public class Main { static int pre[]; static int n; static int m, a, b; static char hand; static Scanner sn = new Scanner(System.in); public static void main(String[] args) { n = sn.nextInt(); m = sn.nextInt(); pre = new int[n + 1]; for(int i = 1; i <= n; i++) pre[i] = i; for (int i = 0; i < m; i++) { hand = sn.next().charAt(0); a = sn.nextInt(); b = sn.nextInt(); if (hand == 'M') pre[find(a)] = pre[find(b)]; else { if (find(a) != find(b)) { System.out.println("No"); } else System.out.println("Yes"); } } } public static int find(int b) { if (pre[b] != b) pre[b] = find(pre[b]); return pre[b]; } }

感觉都能理解,但是不懂为什么第一个代码要WA,请指教!

最新回复(0)