I hope you know the beautiful Union-Find structure. In this problem, you’re to implement something similar, but not identical. The data structure you need to write is also a collection of disjoint sets, supporting 3 operations:
1 p q Union the sets containing p and q. If p and q are already in the same set, ignore this command. 2 p q Move p to the set containing q. If p and q are already in the same set, ignore this command. 3 p Return the number of elements and the sum of elements in the set containing p.
Initially, the collection contains n sets: {1}, {2}, {3}, ..., {n}.
Input
There are several test cases. Each test case begins with a line containing two integers n and m (1 ≤ n,m ≤ 100,000), the number of integers, and the number of commands. Each of the next m lines contains a command. For every operation, 1 ≤ p,q ≤ n. The input is terminated by end-of-file (EOF).
Output
For each type-3 command, output 2 integers: the number of elements and the sum of elements.
Explanation Initially: {1}, {2}, {3}, {4}, {5} Collection after operation 1 1 2: {1,2}, {3}, {4}, {5} Collection after operation 2 3 4: {1,2}, {3,4}, {5} (we omit the empty set that is produced when taking out 3 from {3}) Collection after operation 1 3 5: {1,2}, {3,4,5} Collection after operation 2 4 1: {1,2,4}, {3,5}
Sample Input
5 7 1 1 2 2 3 4 1 3 5 3 4 2 4 1 3 4 3 3
Sample Output
3 12 3 7 2 8
题意:
初始时,一共有n个元素的组合1,2,3....n
给出三个操作
1 p q:合并p,q所在的集合
2 p q:把p移动到q所在的集合
3 p:输出p所在的集合的元素的个数,集合元素的总和;
思路:带权并查集;
#include<stdio.h>
int pre[200000+10],a[200000+10],b[200000+10];
int find(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
int main()
{
int m,n,i,k,p1,p2,p;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=0;i<=n;i++)
{
pre[i]=pre[i+n]=i+n;
a[i]=a[i+n]=1;
b[i]=b[i+n]=i;
}
while(m--)
{
scanf("%d",&k);
if(k==1)
{
scanf("%d %d",&p1,&p2);
int fx=find(p1);
int fy=find(p2);
if(fx!=fy)
{
pre[fx]=fy;
a[fy]+=a[fx];
b[fy]+=b[fx];
}
}
else if(k==2)
{
scanf("%d %d",&p1,&p2);
int fx=find(p1);
int fy=find(p2);
if(fx!=fy)
{
pre[p1]=fy;
a[fy]++;
a[fx]--;
b[fy]+=p1;
b[fx]-=p1;
}
}
else if(k==3)
{
scanf("%d",&p);
printf("%d %d\n",a[find(p)],b[find(p)]);
}
}
}
return 0;
}