UVA-11987
I hope you know the beautiful Union-Find structure. In this problem, you’re to implement somethingsimilar, 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 containingp.Initially, the collection contains n sets: {1}, {2}, {3}, . . . , {n}.InputThere 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 linescontains a command. For every operation, 1 ≤ p, q ≤ n. The input is terminated by end-of-file (EOF).OutputFor each type-3 command, output 2 integers: the number of elements and the sum of elements.ExplanationInitially: {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 whentaking 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 Input5 71 1 22 3 41 3 53 42 4 13 43 3Sample Output3 123 72 8
AC代码为:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int father[maxn], id[maxn], sum[maxn], cnt[maxn];
int n, m, p, q, dt, temp;
int Find(int a)
{
return a == father[a] ? a : Find(father[a]);
}
void Union_set(int a, int b)
{
int x = Find(a);
int y = Find(b);
if (x != y)
{
father[y] = x;
cnt[x] += cnt[y];
sum[x] += sum[y];
}
}
void Move_set(int a)
{
int fa = Find(id[a]);
sum[fa] -= a;
cnt[fa]--;
id[a] = ++temp;
father[id[a]] = temp;
cnt[id[a]] = 1;
sum[id[a]] = a;
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
temp = n;
for (int i = 0; i <= n; i++)
{
father[i] = i;
sum[i] = i;
id[i] = i;
cnt[i] = 1;
}
while (m--)
{
cin >> dt;
if (dt == 1)
{
cin >> p >> q;
Union_set(id[p], id[q]);
}
else if (dt == 2)
{
cin >> p >> q;
int t1 = Find(id[p]);
int t2 = Find(id[q]);
if (t1 != t2)
{
Move_set(p);
Union_set(id[p], id[q]);
}
}
else
{
cin >> p;
int fat = Find(id[p]);
cout << cnt[fat] << " " << sum[fat] << endl;
}
}
}
return 0;
}