HOJ 3635 Dragon Balls(并查集)

并查集
题目意思:
T a b 表示把a龙珠所在的城里的所有龙珠运到b所在的城里
Q a 表示对a的询问,要求输出 a所在的城, a所在的城里一共有多少个龙珠, a经过几次到达现在所在的城的。(移动的次数)
本题要点:
1、主要是记录移动次数:
其实每个根结点都是最多移动一次的,
所以记录移动次数把自己的加上父亲结点的就是移动总数了

#include 
#include 
#include 
using namespace std;
const int MaxN = 10010;
int sum[MaxN];
int trans[MaxN];	//转换次数
int fa[MaxN];
int T, n, m;

int get(int x)
{
	if(fa[x] == x)
		return x;
	int tmp = fa[x];
	fa[x] = get(fa[x]);
	trans[x] += trans[tmp];
	return fa[x];
} 

void merge(int x, int y)
{
	int fax = get(x);
	int fay = get(y);
	if(fax != fay)
	{
		fa[fax] = fay;
		sum[fay] += sum[fax];
		trans[fax] = 1;
	}
}

void init()
{
	for(int i = 1; i <= n; ++i)
	{
		fa[i] = i, sum[i] = 1, trans[i] = 0;
	}
}

int main()
{
	char ch[2];
	int x, y;
	scanf("%d", &T);
	for(int t = 1; t <= T; ++t)
	{
		scanf("%d%d", &n, &m);
		init();
		printf("Case %d:\n", t);
		for(int i = 0; i < m; ++i)
		{
			scanf("%s", ch);
			if(ch[0] == 'T')
			{
				scanf("%d%d", &x, &y);
				merge(x, y);
			}else{
				scanf("%d", &x);
				int y = get(x);
				printf("%d %d %d\n", y, sum[y], trans[x]);
			}
		}
	}
	return 0;
}

/*
2
3 3
T 1 2
T 3 2
Q 2
3 4
T 1 2
Q 1
T 1 3
Q 1
*/

/*
Case 1:
2 3 0
Case 2:
2 2 1
3 3 2
*/

你可能感兴趣的:(并查集,HOJ)