您的位置:首页 > 其它

UVA - 11987 Almost Union-Find(带删除的并查集)

2015-03-27 01:08 459 查看
Almost Union-Find

Time Limit: 1000MSMemory Limit: Unknown64bit IO Format: %lld & %llu
Submit Status

Description





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!

带删除的并查集,用id[i]=ii代表数字i当前的位置,每次删除把id[i]指向其他位置,原来的位置舍去。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

const int MAXN = 2e5 + 5;
int F[MAXN], cnt[MAXN], id[MAXN], sum[MAXN];
int dex;
int n, k;

void init()
{
	for (int i = 0; i <= n; i++)
	{
		F[i] = id[i] = sum[i] = i;
		cnt[i] = 1;
	}
	dex = n;
}

int find(int t)
{
	if (F[t] == t) return t;
	return F[t] = find(F[t]);
}

void Union(int a, int b)
{
	int p = find(a);
	int q = find(b);
	if (p != q)
	{
		F[p] = q;
		cnt[q] += cnt[p];
		sum[q] += sum[p];
	}
}

void move(int a)
{
	int p = find(id[a]);
	cnt[p]--;
	sum[p] -= a;
	id[a] = ++dex;
	F[dex] = dex;
	cnt[dex] = 1;
	sum[dex] = a;
}

int main()
{
	while (scanf("%d%d", &n, &k) != EOF)
	{
		init();
		int op,a,b;
		while (k--)
		{
			cin >> op;
			if (op == 1)
			{
				cin >> a >> b;
				Union(id[a], id[b]);
			}
			else if (op == 2)
			{
				cin >> a >> b;
				int p = find(id[a]);
				int q = find(id[b]);
				if (p != q)
				{
					move(a);
					Union(id[a], id[b]);
				}
			}
			else if (op == 3)
			{
				cin >> a;
				int p = find(id[a]);
				cout << cnt[p] << " " << sum[p] << endl;
			}
		}
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: