
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
#include<stdio.h>
int parent[101010];
int num[101001];//表示移动次数 
int rank[100010];//表示该地有多少颗龙珠 
int find(int x)
{
	if(x==parent[x]) return x;
	
    int t=parent[x];
    parent[x]=find(parent[x]);//压缩路径 ,都指向根节点 
    num[x]+=num[t];//每个球移动的次数等于本身移动的个数加上父节点移动的次数
    return parent[x];	 
//	int r=x;
//	while(r!=parent[r])
//	{
//		num[r]+=num[parent[r]]; //num需要通过加上父节点来更新 
//		r=parent[r];						
//	}		
//	int i=x,j;//路径压缩 
//	while(i!=r)
//	{		
//		j=parent[i];
//		parent[i]=r;
//		i=j;
//	}
//	return r;
}
void join(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
	{
		parent[fx]=fy;//把fx的根节点赋予fy,即把城市fx的龙珠给城市移到fy 
		num[fx]=1;//头结点移动一次 
		rank[fy]+=rank[fx];//根节点代表城市 
	}
}
int main()
{
	int t;
	int n,m,a,b;
	int i;
	char ch;
	int cnt=0;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		getchar();
		for(i=1;i<=n;++i)
		{
			parent[i]=i;
			num[i]=0;
			rank[i]=1; 
		}
//		int flag=1;
		printf("Case %d:\n",++cnt);
		while(m--)
		{
			scanf("%c",&ch);
			if(ch=='T')
			{
				scanf("%d%d",&a,&b);
				getchar();
				join(a,b);//把a所在的城市的龙珠调到城市b 
			}
			else if(ch=='Q')
			{
				scanf("%d",&a);
				getchar();
				int temp=find(a); //找龙珠a在哪个城市,在找的时候不停的会加上它的父节点 
//				if(flag) {
//					printf("Case %d:",++cnt);
//					flag=0;
//				}
				printf("%d %d %d\n",temp,rank[temp],num[a]); 
			} 
		}
	}
	return 0;
}
#include<stdio.h>
int parent[101010];
int num[101001];//表示移动次数 
int rank[100010];//表示该地有多少颗龙珠 
int find(int x)
{
	if(x==parent[x]) return x;
	
    int t=parent[x];
    parent[x]=find(parent[x]);//压缩路径 ,都指向根节点 
    num[x]+=num[t];//每个球移动的次数等于本身移动的个数加上父节点移动的次数
    return parent[x];	 
//	int r=x;
//	while(r!=parent[r])
//	{
//		num[r]+=num[parent[r]]; //num需要通过加上父节点来更新 
//		r=parent[r];						
//	}		
//	int i=x,j;//路径压缩 
//	while(i!=r)
//	{		
//		j=parent[i];
//		parent[i]=r;
//		i=j;
//	}
//	return r;
}
void join(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
	{
		parent[fx]=fy;//把fx的根节点赋予fy,即把城市fx的龙珠给城市移到fy 
		num[fx]=1;//头结点移动一次 
		rank[fy]+=rank[fx];//根节点代表城市 
	}
}
int main()
{
	int t;
	int n,m,a,b;
	int i;
	char ch;
	int cnt=0;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		getchar();
		for(i=1;i<=n;++i)
		{
			parent[i]=i;
			num[i]=0;
			rank[i]=1; 
		}
		int flag=1;
//		printf("Case %d:\n",++cnt);
		while(m--)
		{
			scanf("%c",&ch);
			if(ch=='T')
			{
				scanf("%d%d",&a,&b);
				getchar();
				join(a,b);//把a所在的城市的龙珠调到城市b 
			}
			else if(ch=='Q')
			{
				scanf("%d",&a);
				getchar();
				int temp=find(a); //找龙珠a在哪个城市,在找的时候不停的会加上它的父节点 
				if(flag) {
					printf("Case %d:\n",++cnt);
					flag=0;
				}
				printf("%d %d %d\n",temp,rank[temp],num[a]); 
			} 
		}
	}
	return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
Dragon Balls HDU杭电3635 【并查集,递归的方法找根节点】
原文:http://blog.csdn.net/yuzhiwei1995/article/details/47209375