la 3027 带权值的并查集
题目是说, 对于一个给定n个数字的集合,我每次有2种操作,一个是I u v 是说,把u的祖先设置为v(f[u]=v),然后u到v的距离变成|u-v|%1000,也就是权值。
E u 是说,询问u到其祖先的距离。
并查集找到根节点,查找中维护权值,两个数组pa[],d[],一个是集合代表元,一个是到根的距离
1 #include <cstdio> 2 2 #include <algorithm>//just for abs() 3 3 using namespace std; 4 4 const int maxn = 1e5; 5 5 int pa[maxn],d[maxn]; 6 6 int find(int x){//find represnet element,maintain the d[x] 7 7 if (x != pa[x]){ 8 8 int root = find(pa[x]); 9 9 d[x] += d[pa[x]]; 10 10 return pa[x] = root; 11 11 } 12 12 else return pa[x]; 13 13 } 14 14 int main(){ 15 15 int T; 16 16 scanf("%d",&T); 17 17 while(T--){ 18 18 int n,u,v; 19 19 char cmd[9]; 20 20 scanf("%d",&n); 21 21 for (int i=1;i<=n;i++){pa[i]=i;d[i]=0;} 22 22 while(scanf("%s",cmd) && cmd[0] != 'O'){ 23 23 if (cmd[0]=='E'){ 24 24 scanf("%d",&u); 25 25 find(u); 26 26 printf("%d\n",d[u]); 27 27 } 28 28 if(cmd[0]=='I'){ 29 29 scanf("%d%d",&u,&v); 30 30 pa[u]=v; 31 31 d[u] = abs(u-v)%1000; 32 32 } 33 33 } 34 34 } 35 35 return 0; 36 36 }