0
点赞
收藏
分享

微信扫一扫

LA3027简单带权并查集

题意:
      有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少?


思路:

可以直接简单带权并查集就能搞定,核心代码是这样,设s_x[i]表示i到自己父亲节点的距离,然后

//处理并查集的时候

int finds(int x)

{

if(x == mer[x]) return x;

int k = mer[x];

mer[x] = finds(mer[x]);

mer[x] += mer[k];

return mer[x];

}



//建立关系的时候



mer[a] = b;

s_x[a] = abs(a - b) % 1000



//询问的时候

x = finds(a);//这一部别忘记了,因为并查集用了路径压缩,查询一次之后才能更新到他到根的距离,不然后可能只是他到他上一个节点的距离,查询后经过路径压缩会把他上一个节点变成他的根节点。

printf(s_x[a]);









#include<stdio.h>

#include<string.h>



#define N 22000



int mer[N] ,s_x[N];



int abss(int x)

{

return x > 0 ? x : -x;

}



int finds(int x)

{

if(x == mer[x]) return x;

int k = mer[x];

mer[x] = finds(mer[x]);

s_x[x] =(s_x[x] + s_x[k]);

return mer[x];

}



int main ()

{

int t ,n ,a ,b;

char str[5];

scanf("%d" ,&t);

while(t--)

{

scanf("%d" ,&n);

for(int i = 0 ;i <= n ;i ++)

mer[i] = i ,s_x[i] = 0;

while(~scanf("%s" ,str) && str[0] != 'O')

{

if(str[0] == 'I')

{

scanf("%d %d" ,&a ,&b);

mer[a] = b;

s_x[a] = abss(a - b) % 1000;

}

else

{

scanf("%d" ,&a);

finds(a);

printf("%d\n" ,s_x[a]);

}

}

}

return 0;

}



举报

相关推荐

0 条评论