【并查集】UVALive3027 Corporative Network
并查集——维护到根节点距离的d数组
题目大意
对n个节点操作,加边 or 询问某节点到根节点的距离
说一下思路
之前做过一道求连通分支最大元素个数的题目,维护的是一个cnt[ ]数组(在加边的过程中);比较这道题,可以考虑维护到根节点的距离d[ ]数组。
思路:记下每个节点到父亲节点的距离为d[i],然后在路径压缩时维护这个d数组;
在加边时只有这两个节点中的父亲节点的d需要维护,并不需要查操作,这一点的区别是相当大的!而怎样得到某节点u到根节点的距离呢?查操作。查操作本身带路径压缩的,所以不可能直接得到最终答案,必须一边路径压缩,一边维护数组d,最后输出d[u]即可
★维护过程与路径压缩同时进行,想想还是有点小麻烦!
参考代码
#include<bits/stdc++.h>
using namespace std;
const int _max = 2e4 + 10;
char cmd[2];
int n,a,b,pre[_max],d[_max];
void init(){
for(int i = 1; i <= n; ++ i){
pre[i] = i;//每个元素所在集合为其自身
d[i] = 0;//每个节点到父亲节点的距离为0
}
}
int find(int x){//返回元素x的根节点,路径压缩过程中维护d[]数组
if( x == pre[x]) return x;
int root = find(pre[x]);
d[x] += d[pre[x]];
return pre[x] = root;
}
void join(int a,int b){//并,按要求合并边(a,b)
pre[a] = b;
d[a] = (abs(a - b))%1000;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
int T;cin>>T;
while(T--){
scanf("%d",&n);
init();
while(scanf("%s",cmd) == 1 && cmd[0] != ‘O‘){
if(cmd[0] == ‘I‘){
scanf("%d%d",&a,&b);
join(a,b);
}
else{
scanf("%d",&a);
find(a);
printf("%d\n",d[a]);
}
}
}
return 0;
}
- 加粗
Ctrl + B
- 斜体
Ctrl + I
- 引用
Ctrl + Q
- 插入链接
Ctrl + L
- 插入代码
Ctrl + K
- 插入图片
Ctrl + G
- 提升标题
Ctrl + H
- 有序列表
Ctrl + O
- 无序列表
Ctrl + U
- 横线
Ctrl + R
- 撤销
Ctrl + Z
- 重做
Ctrl + Y
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-05 18:51:24