Almost Union-Find ()

最近在练并查集,好头疼啊。

本来经过几次练习自我感觉还是不错的,遇到这个题却搞的头都大了。。。。。唉,或许这就是菜鸡罢。。。。。。

不说了上代码。

#include<iostream>
#include<queue>
#include<stdio.h>
#include<string.h>

using namespace std;

#define MAXN 200005

int board[MAXN];
int real[MAXN];
int cnt[MAXN];
long long sum[MAXN];
int deathline;

int find(int a)
{
	if(board[a] == a)return a;
	return board[a] = find(board[a]);
}

void join(int a,int b)
{
	int A = find(real[a]);
	int B = find(real[b]);
	if(A!=B)
	{
		board[A] = B;
		cnt[B] += cnt[A];
		sum[B] += sum[A];
	}
}

void Del(int a)
{
	int t = find(real[a]);
	cnt[t]--;
	sum[t] -= (long long)a;
	real[a] = ++deathline;
	sum[real[a]] = (long long)a;
	cnt[real[a]] = 1;
	board[real[a]] = real[a];
}

int main()
{
	int N,M;
	while(scanf("%d %d",&N,&M)!=EOF)
	{
		for(int i=1 ; i<=N ; i++)
		{
			real[i] = board[i] = i;
			sum[i] = (long long)i;
			cnt[i] = 1;
		}
		deathline = N;
		while(M--)
		{
			int a;
			scanf("%d",&a);
			if(a == 1)
			{
				int p,q;
				scanf("%d %d",&p,&q);
				join(p,q);
			}
			else if(a == 2)
			{
				int p,q;
				scanf("%d %d",&p,&q);
				if(find(real[p]) != find(real[q]))
				{
					Del(p);
					join(p,q);
				}
			}
			else if(a == 3)
			{
				int p;
				scanf("%d",&p);
				printf("%d %lld
",cnt[find(real[p])],sum[find(real[p])]);
			}
		}
	}
	return 0;
}



原文地址:https://www.cnblogs.com/vocaloid01/p/9514317.html