并查集:维护到根节点距离d
M操作: 合并两个节点所在集合
C操作:
判断两个节点是否在同一集合
不在同一个集合, 返回-1
在同一个集合, max(abs(d[x] - d[y]) - 1, 0)
并查集维护, 节点a与b, 对应根节点pa与pb
合并:
1. pa指向pb( f[pa] = pb )
2. pa的距离到pb根节点的距离等于pb集合的大小( d[pa] = size[pb])
3. pb集合大小 加等于 pa集合的大小 ( size[pb] += size[pa] )
查找:
1. 点a到其根节点pa的距离为 ( d[a] += d[f[a]] )
2. 点a的根节点为pa ( f[a] = oa )
import java.io.*;
class Main{
static BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter log = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 30010;
static int[] f = new int[N], size = new int[N], d = new int[N];
public static void main(String[] args) throws Exception{
int t = Integer.valueOf(read.readLine());
for(int i = 0; i < N; i++) {
f[i] = i;
size[i] = 1;
}
while(t-- > 0){
String[] ss = read.readLine().split(" +");
int a = Integer.valueOf(ss[1]), b = Integer.valueOf(ss[2]);
switch(ss[0]){
case "M":
union(a, b);
break;
case "C":
int f1 = find(a), f2 = find(b);
if(f1 == f2) log.write(Math.max(0, Math.abs(d[a] - d[b]) - 1) + "\n");
else log.write("-1\n");
break;
default:
break;
}
}
log.flush();
}
public static void union(int a, int b){
int f1 = find(a), f2 = find(b);
if(f1 == f2) return;
f[f1] = f2;
d[f1] = size[f2];
size[f2] += size[f1];
}
public static int find(int x){
if(x != f[x]){
int root = find(f[x]);
d[x] += d[f[x]];
f[x] = root;
}
return f[x];
}
}