“M a b”,将编号为a和b的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
“Q a b”,询问编号为a和b的两个数是否在同一个集合中;
解答
import java.io.*;
publicclassMain{ staticfinalint N = 100010; staticint[] p = newint[N]; staticint m; staticint n; publicstaticintfind(int x){ if(p[x]!=x) p[x]=find(p[x]); return p[x]; } publicstaticvoidmain(String[] args)throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] line = br.readLine().split(" "); int n = Integer.parseInt(line[0]); // n个整数 int m = Integer.parseInt(line[1]);// m个指令 //一开始每个数都是一个集合 for(int i=1;i<=n;i++){ p[i]=i; } while(m-->0){ String[] s = br.readLine().split(" "); int a = Integer.parseInt(s[1]); int b = Integer.parseInt(s[2]); if(s[0].equals("M")){ p[find(a)] = find(b); }else{ if(find(a)!=find(b)){ System.out.println("No"); }else{ System.out.println("Yes"); } } } } }
Ac837 连通块中数的数量
描述
给定一个包含n个点(编号为1~n)的无向图,初始时图中没有边。
现在要进行m个操作,操作共有三种:
“C a b”,在点a和点b之间连一条边,a和b可能相等;
“Q1 a b”,询问点a和点b是否在同一个连通块中,a和b可能相等;
“Q2 a”,询问点a所在连通块中点的数量;
分析:多了统计数量这个操作
解答
import java.io.*; publicclassMain{ staticfinalint N = 100010; staticint[] p = newint[N]; staticint[] size = newint[N]; staticint m; staticint n; publicstaticintfind(int x){ if(p[x]!=x) p[x] = find(p[x]); return p[x]; } publicstaticvoidmain(String[] args)throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] line = br.readLine().split(" "); int n = Integer.parseInt(line[0]); // n个整数 int m = Integer.parseInt(line[1]);// m个指令 //初始化 for(int i=1;i<=n;i++){ p[i]=i; size[i] = 1; } while(m-->0){ String[] s = br.readLine().split(" ");
if(s[0].equals("C")){ int a = Integer.parseInt(s[1]); int b = Integer.parseInt(s[2]); a = find(a); b=find(b); if(a != b){ p[a] = b; size[b] += size[a]; // a插到b下面 } }elseif(s[0].equals("Q1")){ int a = Integer.parseInt(s[1]); int b = Integer.parseInt(s[2]); if(find(a)!=find(b)){ System.out.println("No"); } else{ System.out.println("Yes"); } }else{ int a = Integer.parseInt(s[1]); System.out.println(size[find(a)]); } } } }