利用并查集的路径压缩来更新距离
#include <stdio.h>
const int max_n = 20000+100;
struct node{
int len2father;
int father_index;
};
struct node node_arr[max_n];
int _abs(int n){
return n<0 ? n*(-1) : n;
}
void merge(int child, int father){
node_arr[child].father_index = father;
node_arr[child].len2father = _abs(child-father)%1000;
}
//update the length between the child node and the father node while compressing the path
int get_root(int child){
int root, father;
if(node_arr[child].father_index == child){
return child;
}
father = node_arr[child].father_index;
root = get_root(father);
node_arr[child].len2father += node_arr[father].len2father;
node_arr[child].father_index = root;
return root;
}
int main(void){
int case_n, node_n, i;
int child, father;
char oper[10];
//freopen("input.dat", "r", stdin);
scanf("%d", &case_n);
while(case_n--){
scanf("%d", &node_n);
//init
for(i=1; i<=node_n; i++){
node_arr[i].father_index = i;
node_arr[i].len2father = 0;
}
while(1){
scanf("%s", oper);
if('O' == *oper)
break;
if('I' == *oper){
scanf("%d %d", &child, &father);
merge(child, father); //when merging, don't compress the path
}
else if('E' == *oper){
scanf("%d", &child);
get_root(child);
printf("%d\n", node_arr[child].len2father ); //only compress the path when search the root index
}
}
}
return 0;
}