【并查集】UVALive3027 Corporative Network
2015-08-26 10:24
549 查看
【并查集】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
相关文章推荐
- HDU-1213-How Many Tables
- Longest Consecutive Sequence,Distinct Subsequences,Interleaving String,Scramble String
- SARS病毒传染 并查集
- HDU 1213
- CSU1307 并查集+SPFA
- BestWiring——Kruskal算法&并查集
- HDU-1233 还是畅通工程(最小生成树&并查集)
- Simon-【深入理解数据结构】有根树的不同实现① —— 并查集
- 家族
- poj 1417 True Liars 解题报告 并查集 DP
- poj 1161
- 并查集——HDOJ 1213How Many Tables解题报告
- 最小生成树——HDOJ 2988 Dark roads解题报告
- HDU 1198 Farm Irrigation(并查集)
- hdu 1213 How Many Tables(并查集,简单题)
- hud 1233 还是畅通工程( kruskal和prim两种方法)
- hdu 1863 畅通工程 (最小生成树kruskal 算法)
- hdu 1213并查集
- hdu 1272并查集
- hdu 1198并查集