2、题目大意;
给定一些操作:
1 a b是合并两个数a b(直接用merge(a,b))
2 a b是将a从原来所在集合中删除,将a移动到b所在的集合中(delete(a),merge(a,b))
3 a 是查询a所在的集合有 多少个数,以及这些数的和,需要打印
3、题目:
Problem A
Almost Union-Find
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!
4、代码:
#include<stdio.h>
#include<string.h>
#define N 200005
int set[N];
char op;
int flag[N];
long long sum[N];
int count[N];
int id[N];
int cnt;
int find(int x)
{
int r=x;
while(r!=set[r])
r=set[r];
int i=x;
while(i!=r)
{
int j=set[i];
set[i]=r;
i=j;
}
return r;
}
void Delete(int x)
{
int fx = find(id[x]);
count[fx]--;
sum[fx]-= x;
id[x]=++cnt;
set[id[x]]=id[x];
count[id[x]] = 1;
sum[id[x]] = x;
}
void merge(int x,int y)
{
int fx=find(id[x]);
int fy=find(id[y]);
//if(fx!=fy)
//{
set[fx]=fy;
count[fy]+=count[fx];
sum[fy]+=sum[fx];
//}
}
int main()
{
int n,m,a,b,c,d,e;
while(scanf("%d%d",&n,&m)!=EOF)
{
getchar();
cnt=n;//赋值错了
for(int i=1; i<=n; i++)
{
set[i]=i;
count[i]=1;
sum[i]=i;
id[i]=i;
}
for(int i=1; i<=m; i++)
{
scanf("%c",&op);
if(op=='1')
{
scanf("%d%d",&a,&b);
getchar();
if(find(id[a])!=find(id[b]))
merge(a,b);
//merge(a,b);
}
else if(op=='2')
{
scanf("%d%d",&c,&d);
//merge(id[c],id[d]);
getchar();
if(find(id[c])!=find(id[d]))
{Delete(c);
merge(c,d);
}
}
else if(op=='3')
{
//printf("****\n");
scanf("%d",&e);
getchar();
//printf("e==%d\n",e);
int ee=find(id[e]);
printf("%d %lld\n",count[ee],sum[ee]);
}
}
}
return 0;
}
/*
5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
*/