Title: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18692
Test instructions: Design A and check set, support three kinds of operations ① merge two collections ② move one element of one collection to another set ③ query the number of elements and the sum of elements of a collection
Analysis: Since the operation ② may cause the entire set to be moved ( remove the root node ), then the initialization, the id+n as the root node is good.
Code:
#include <iostream> #include <cstdio>using namespace std;const int maxn = 2e6;const int over = 1e6; int sum[maxn],size[maxn],fa[maxn],n,q;int Find (int x) {if (fa[x]==x) return x;int root=find (fa[x]); return fa[x]=root;} int main () {int i,j,tp,x,y;while (scanf ("%d%d", &n,&q)!=eof) {for (i=0;i<=n;i++) fa[i]=i+over;for (i=over;i <=over+n;i++) {fa[i]=i; Sum[i]=i-over; Size[i]=1;} while (q--) {scanf ("%d", &TP), if (tp==1) {scanf ("%d%d", &x,&y), int root1=find (x), Root2=find (y), if (root1== ROOT2) continue; Fa[root1]=root2; SUM[ROOT2]+=SUM[ROOT1]; SIZE[ROOT2]+=SIZE[ROOT1];} else if (tp==2) {scanf ("%d%d", &x,&y), int root1=find (x), Root2=find (y), if (ROOT1==ROOT2) continue; size[root1]--; size[root2]++; Sum[root1]-=x; Sum[root2]+=x; Fa[x]=root2;} ELSE{SCANF ("%d", &x), int root=find (x);p rintf ("%d%d\n", Size[root],sum[root]);}} return 0;}
UVA 11987 almost Union-find (and set)