並查集:互不相交的集合
並查集的3種操作:
(1)Make_Set()
把每一個元素初始化爲一個集合,初始化後的每一個元素的父節點是它本身
(2)Find_Set(int x)
查找一個元素所在的集合,關鍵在於尋找這個元素所在集合的祖先
(3)Union(int x, int y)
合併x和y所在的集合,一個集合的祖先指向另一個集合的祖先
題目:x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。先輸入10個人(編號從1-10)及7組親戚關係,然後輸入3組數據,問這三組數據是不是親戚關係?
輸入
10 7
2 4
5 7
1 3
8 9
1 2
5 6
2 3
3
3 4
7 10
8 9
輸出
Yes
No
Yes
package com.java.study; import java.util.Scanner; public class UnionColl { int [] father; int [] rank; public UnionColl(){} private void Make_Set(){ for(int i = 0 ; i < father.length ; i++){ father[i] = i;//根據實際情況指定的父節點可變化 rank[i] = 0;//根據實際情況初始化秩也有所變化 } } private int Find_Set(int x){ if(x!=father[x]){ father[x] = Find_Set(father[x]);//將查找路徑的所有節點都指向根節點 } return father[x]; } void Union(int x, int y){ int f1 = Find_Set(x); int f2 = Find_Set(y); if(f1!=f2){ father[f1] = f2; } } public void go(){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); father = new int[n+1]; rank = new int[n+1]; Make_Set(); for(int i = 1; i <= m; i++){ int a = sc.nextInt(); int b = sc.nextInt(); int x = Find_Set(a); int y = Find_Set(b); Union(x,y); } int k = sc.nextInt(); for(int i = 1 ; i <= k ;i++){ int x = sc.nextInt(); int y = sc.nextInt(); if(Find_Set(x)==Find_Set(y)) System.out.println("Yes"); else System.out.println("No"); } } public static void main(String[] args) { UnionColl uc = new UnionColl(); uc.go(); } }