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 }
View Code

 

posted @ 2016-05-17 22:06  banana16314  阅读(208)  评论(0编辑  收藏  举报