有点有趣的并查集问题,类似于食物链而略简单
使用sum[i]表示以i为祖先的并查集的元素个数(不包含i), 以dis[i]表示i到其祖先的距离,每次getfather时根据x的直接父亲来更新x的dis值,每次修改操作时用sum[y]更新dis[x],用sum[x]更新sum[y],最后输出时直接利用两个点的dis值得解
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 6 const int maxn = 30000 + 500; 7 int father[maxn], dis[maxn]; 8 int sum[maxn]; 9 char c; 10 int x, y; 11 int t; 12 13 int getfather(int x) { 14 if (father[x] == x) return (x); 15 int cur = father[x]; 16 father[x] = getfather(father[x]); 17 dis[x] = dis[x] + dis[cur]; 18 return (father[x]); 19 } 20 21 int main () { 22 scanf("%d", &t); 23 for (int i = 1; i <= 30000; i++) { 24 father[i] = i; 25 } 26 for (int i = 1; i <= t; i++) { 27 scanf(" %c %d %d", &c, &x, &y); 28 if (c == 'M') { 29 int tx = getfather(x); 30 int ty = getfather(y); 31 if (tx != ty) { 32 father[tx] = ty; 33 dis[tx] = ++sum[ty]; 34 sum[ty] += sum[tx]; 35 } 36 } else { 37 int tx = getfather(x); 38 int ty = getfather(y); 39 if (tx != ty) printf("-1 "); 40 else printf("%d ", abs(dis[x] - dis[y]) - 1); 41 } 42 } 43 44 return 0; 45 }