Uva11987 Almost Union-Find 并查集带删除
2017-11-27 21:18
288 查看
大家都很强, 可与之共勉。
题意:搞一个数据结构,支持如下操作,每组数据共有m个操作:
1 p q:合并p和q所在集合,如果已经在一个集合中,忽略此命令
2 p q:把p移动到q所在集合,如果已经在一个集合中,忽略此命令
3 p:输出p所在集合的元素个数和该集合所有元素之和
题解:
建立每个点一个虚点,设为根,每个点的初始祖先即为虚点。然后合并集合是合并初始祖先。移动单个元素就直接把实点到父亲的根切断,然后直接改父亲,计算贡献。这样一定有一个性质就是一颗树上叶子结点一定是实点。
注意有多组数据
# include <bits/stdc++.h> inline int read ( ) { register int x, c ; while ( isspace ( c = getchar ( ) ) ) ; for ( x = -48 + c ; isdigit ( c = getchar ( ) ) ; ( x *= 10 ) += c - 48 ) ; return x ; } # define N 100010 class UnionFindSet { private : int fa [N << 1] ; public : UnionFindSet ( ) { } UnionFindSet ( int n ) { for ( register int i = 1 ; i <= n ; ++ i ) fa [i] = fa [n + i] = n + i ; } inline int find ( int x ) { while ( x ^ fa [x] ) x = fa [x] = fa [fa [x]] = fa [fa [fa [x]]] ; return x ; } inline void join ( int u, int v ) { fa [find ( u )] = find ( v ) ; } inline void changefa ( int u, int p ) { fa [u] = p ; } } T ; int siz [N << 1], sum [N << 1] ; # undef N int main ( ) { // freopen ( "in.txt", "r", stdin ) ; // freopen ( "out.txt", "w", stdout ) ; int n, m ; while ( ~ scanf ( "%d%d", & n, & m ) ) { T = UnionFindSet ( n ) ; for ( int i = n + 1 ; i <= n + n ; ++ i ) siz [i] = 1, sum [i] = i - n ; while ( m -- ) { int opt ( read ( ) ) ; switch ( opt ) { case 1 : { int p ( read ( ) ), q ( read ( ) ), fp, fq ; if ( ( fp = T.find ( p ) ) ^ ( fq = T.find ( q ) ) ) { T.join ( p, q ) ; siz [fq] += siz [fp] ; sum [fq] += sum [fp] ; } break ; } case 2 : { int p ( read ( ) ), q ( read ( ) ) ; if ( T.find ( p ) == T.find ( q ) ) continue ; -- siz [T.find ( p )], sum [T.find ( p )] -= p ; T.changefa ( p, T.find ( q ) ) ; siz [T.find ( q )] += 1 ; sum [T.find ( q )] += p ; break ; } case 3 : { int u ( read ( ) ) ; printf ( "%d %d\n", siz [T.find ( u )], sum [T.find ( u )] ) ; break ; } } } } }
相关文章推荐
- UVA11987:Almost Union-Find (并查集的删除)
- uva11987 - Almost Union-Find 并查集删除元素
- UVA11987_Almost Union-Find(并查集删除操作)
- UVA - 11987 Almost Union-Find(带删除的并查集)
- UVA - 11987 Almost Union-Find(带删除的并查集)
- UVA 11987 Almost Union-Find(带删除的并查集)
- UVA 11987 Almost Union-Find 并查集节点删除
- uva 11987 Almost Union-Find(并查集的删除操作)
- uva 11987 Almost Union-Find(带删除操作的并查集)
- UVA 11987 Almost Union-Find(并查集的删除)
- UVa-11987 Almost union-find(带删除操作的并查集)
- uva 11987 Almost Union-Find(带删除操作的并查集)
- uva11987 Almost Union-Find(可删除元素的并查集)
- UVA 11987 Almost Union-Find 并查集的删除操作 懒惰标记
- 并查集(删除) UVA 11987 Almost Union-Find
- 11987 - Almost Union-Find(并查集删除操作)
- UVA 11987 Almost Union-Find (带权并查集的操作及并查集的删除操作)
- UVA11987 - Almost Union-Find (并查集带删除)
- UVA 11987 Almost Union-Find(有删除操作的并查集)
- UVA 11987 Almost Union-Find(带有删除操作的并查集)