1. 程式人生 > 實用技巧 >837.連通塊中點的數量

837.連通塊中點的數量

給定一個包含n個點(編號為1~n)的無向圖,初始時圖中沒有邊。
現在要進行m個操作,操作共有三種:
“C a b”,在點a和點b之間連一條邊,a和b可能相等;
“Q1 a b”,詢問點a和點b是否在同一個連通塊中,a和b可能相等;
“Q2 a”,詢問點a所在連通塊中點的數量;

輸入格式

第一行輸入整數n和m。
接下來m行,每行包含一個操作指令,指令為“C a b”,“Q1 a b”或“Q2 a”中的一種。

輸出格式

對於每個詢問指令”Q1 a b”,如果a和b在同一個連通塊中,則輸出“Yes”,否則輸出“No”。
對於每個詢問指令“Q2 a”,輸出一個整數表示點a所在連通塊中點的數量
每個結果佔一行。

資料範圍

1≤n,m≤105

輸入樣例:

5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5

輸出樣例:

Yes
2
3

參考程式碼

import java.util.Scanner;

public class Main {

	static int[] p = new int[100010];
	static int[] size = new int[100010];

	public static int find(int x) {
		if (p[x] != x) {
			p[x] = find(p[x]);
		}
		return p[x];
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();
		int m = sc.nextInt();
		sc.nextLine();

		for (int i = 1; i <= n; i++) {
			p[i] = i;
			size[i] = 1;
		}

		while ((m--) != 0) {
			String str = sc.nextLine();
			String[] t = str.split(" ");

			if (t[0].equals("C")) {
				int a = Integer.parseInt(t[1]);
				int b = Integer.parseInt(t[2]);
				p[find(a)] = find(b);
				size[b] += size[a];
			} else if (t[0].equals("Q1")) {
				int a = Integer.parseInt(t[1]);
				int b = Integer.parseInt(t[2]);
				if (find(a) == find(b)) {
					System.out.println("Yes");
				} else {
					System.out.println("No");
				}
			} else {
				int a = Integer.parseInt(t[1]);
				System.out.println(size[find(a)]);
			}
		}

		sc.close();
	}
}