HDU 2818 Building Block【并查集+根节点偏移量】
来源:互联网 发布:linux 系统日志 命令 编辑:程序博客网 时间:2024/04/28 05:07
大意:有30000个木块一次在一条线上排开 现在有两种操作 一种是把a木块所在的木块堆全部放到b木块堆的上面
一种是 查询a木块底下有多少块
分析:并查集 偏移量代表相对于根节点的偏移量
一下为根方便建立 然后对于一个下根 用一个数组表示其最顶端的是什么
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 30005; 7 8 int fa[maxn]; 9 int num[maxn];10 int di[maxn];11 12 void init(int n) {13 for(int i = 0; i <= n; i++) {14 fa[i] = i;15 num[i] = 0;16 di[i] = i;17 }18 }19 20 int Find(int x) {21 if(x == fa[x]) return fa[x];22 int fax = fa[x];23 fa[x] = Find(fa[x]);24 num[x] = num[x] + num[fax];25 return fa[x];26 }27 28 int main() {29 int n;30 char a; int x, y;31 while(EOF != scanf("%d",&n) ) {32 init(30000);33 while(n--) {34 scanf("\n%c",&a);35 if(a == 'M') {36 scanf("%d %d",&x, &y);37 int xx = Find(x); int yy = Find(y);38 Find(di[xx]); Find(di[yy]);39 // printf("%d %d %d %d id = %d %d\n", x, y, xx, yy, di[xx], di[yy]);40 if(xx != yy) {41 fa[xx] = yy;42 num[xx] = num[di[yy]] + 1;43 di[yy] = di[xx];44 }45 } else {46 scanf("%d",&x);47 int z = Find(x);48 printf("%d\n", num[x]);49 }50 }51 }52 return 0;53 }
有一点需要注意的是 每次更新完都要进行更新 要不可能会出现这次更新的不会对上次产生影响 也就是第38行
0 0
- HDU 2818 Building Block【并查集+根节点偏移量】
- HDU 2818 Building Block【并查集+根节点偏移量】
- HDU 2818 Building Block(并查集)
- hdu 2818 Building Block(并查集)
- HDU 2818 Building Block (并查集)
- hdu 2818 Building Block (并查集)(根据父节点来更新)
- hdu 2818 Building Block(并查集)
- hdu 2818 Building Block 并查集 路径压缩
- hdu 2818 Building Block (并查集)
- Hdu 2818 Building Block 加权并查集
- HDU 2818 Building Block 带权并查集
- HDU 2818 Building Block(带权并查集)
- hdu 2818 Building Block(带权并查集)
- hdu 2818 Building Block(加权并查集)
- HDU 2818 Building Block 带权并查集
- hdu 2818 Building Block【基础带权并查集】
- hdu 2818 Building Block(带权并查集)
- HDU 2818 Building Block(带权并查集)
- 插入排序
- 强联通分量容易出错的地方
- 0112
- 0113
- HDU 2817 A sequence of numbers【水题|快速幂】
- HDU 2818 Building Block【并查集+根节点偏移量】
- 0114
- HDU 2819 Swap【二分图|启发题】
- 关于多线程栈空间的若干问题
- HDU 2822 Dogs【两次bfs】
- 2015 01 29
- HDU 2824 The Euler function【模板题】
- 0302
- 0328