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). The size of input file does not exceed 5MB.
Output
For each type-3 command, output 2 integers: the number of elements and the sum of elements.
Sample Input
5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
Output for the Sample Input
3 12
3 7
2 8
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}
Rujia Liu’s Present 3: A Data Structure Contest Celebrating the 100th Anniversary of Tsinghua University
Special Thanks: Yiming Li
Note: Please make sure to test your program with the gift I/O files before submitting!
操作1是将两个集合合并,操作2是将p加入集合p中,操作3是查询集合元素的多少以及和。建立一个虚拟的根用id来存储
#include<stdio.h>
#define inf 1001011
int par[inf],cnt[inf],sum[inf],id[inf];
int find(int root)
{
if(par[root]!=root)
par[root]=find(par[root]);
return par[root];
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
int i,j,op,x,y,total=n+1;
for(i=1; i<=n; i++)
{
par[i]=i;
cnt[i]=1;
sum[i]=i;
id[i]=i;
}
while(m--)
{
scanf("%d %d",&op,&x);
if(op==1)
{
scanf("%d",&y);
int r1=find(id[x]);
int r2=find(id[y]);
if(r1!=r2)
{
par[r1]=par[r2];
sum[r2]+=sum[r1];
cnt[r2]+=cnt[r1];
}
}
else if(op==2)
{
scanf("%d",&y);
int r1=find(id[x]);
int r2=find(id[y]);
if(r1!=r2)
{
id[x]=total++;
cnt[r1]--;
sum[r1]-=x;
par[id[x]]=par[id[y]];
cnt[r2]++;
sum[r2]+=x;
}
}
else if(op==3)
{
int k;
k=find(id[x]);
printf("%d %d\n",cnt[k],sum[k]);
}
}
}
}