题目链接:http://acm.hust.edu.cn/vjudge/problem/36132
大意:给出n个结点,一系列操作。对于操作I,输入u,v,把u的父结点设为v,距离为|u-v|mod1000;对于操作E,输入u,输出u到根结点的距离。
思路:两个操作正好对应了并查集的合并和查找,对于操作I,由于v没有父结点,直接令pre[u] = v即可;对于操作E,由于根节点是动态变化的,所以要先更新再查询。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 2e4 + 5;
int n, pre[maxn], dist[maxn];
int find(int x)
{
if (pre[x] == x) return pre[x];
int y = pre[x];
pre[x] = find(pre[x]);
dist[x] += dist[y];
return pre[x];
}
int main()
{
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
memset(dist, 0, sizeof dist);
for(int i = 1; i <= n; i++) pre[i] = i;
char s[2];
while(scanf("%s",s) && s[0] != 'O') {
if (s[0] == 'E') {
int x;
scanf("%d",&x);
find(x);
printf("%d\n",dist[x]);
}
else {
int a,b;
scanf("%d%d",&a,&b);
pre[a] = b;
dist[a] = abs(a-b) % 1000;
}
}
}
}