Dragon Balls HDU杭电3635 【并查集,递归的方法找根节点】

Problem Description

Five hundred years later, the number of dragon balls will increase unexpectedly, so it‘s too difficult for Monkey King(WuKong) to gather all of the dragon balls together.

His country has N cities and there are exactly N dragon balls in the world. At first, for the ith dragon ball, the sacred dragon will puts it in the ith city. Through long years, some cities‘ dragon ball(s) would be transported to other cities. To save physical
strength WuKong plans to take Flying Nimbus Cloud, a magical flying cloud to gather dragon balls.

Every time WuKong will collect the information of one dragon ball, he will ask you the information of that ball. You must tell him which city the ball is located and how many dragon balls are there in that city, you also need to tell him how many times the
ball has been transported so far.

Input

The first line of the input is a single positive integer T(0 < T <= 100).

For each case, the first line contains two integers: N and Q (2 < N <= 10000 , 2 < Q <= 10000).

Each of the following Q lines contains either a fact or a question as the follow format:

T A B : All the dragon balls which are in the same city with A have been transported to the city the Bth ball in. You can assume that the two cities are different.

Q A : WuKong want to know X (the id of the city Ath ball is in), Y (the count of balls in Xth city) and Z (the tranporting times of the Ath ball). (1 <= A, B <= N)

Output

For each test case, output the test case number formated as sample output. Then for each query, output a line with three integers X Y Z saparated by a blank space.

Sample Input

2
3 3
T 1 2
T 3 2
Q 2
3 4
T 1 2
Q 1
T 1 3
Q 1

Sample Output

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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 09:02:37

Dragon Balls HDU杭电3635 【并查集,递归的方法找根节点】的相关文章

杭电1272 并查集找环+判断连通

杭电1272 并查集找环+判断连通 E - E Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1272 Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B

hdu 3635 Dragon Balls 【基础带权并查集】

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3461    Accepted Submission(s): 1348 Problem Description Five hundred years later, the number of dragon balls will increase unexpect

『ACM C++』HDU杭电OJ | 1415 - Jugs (灌水定理引申)

今天总算开学了,当了班长就是麻烦,明明自己没买书却要带着一波人去领书,那能怎么办呢,只能说我善人心肠哈哈哈,不过我脑子里突然浮起一个念头,大二还要不要继续当这个班委呢,既然已经体验过就可以适当放下了吧,用心在自己的研究上.晚上级会开完也就八点多了,开始打打题,今天在HDU杭电的ACM集训题看到一个奇葩的题,前来献上. 今日推荐: <全球风暴> 一部宇宙航空和地球气候片的良心佳作,后期特效建模都是特别杠杠的大片,不会让你失望的哟,我已经三刷了哈哈哈.这部片在爱奇艺有上线,有兴趣的朋友可以看看鸭.

hdu 3234 Exclusive-OR (并查集+异或性质)

Exclusive-OR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2177    Accepted Submission(s): 603 Problem Description You are not given n non-negative integers X0, X1, ..., Xn-1 less than 220 ,

HDU 4496 D-City (并查集)

题意:给你n个点m条边,问删除前i条边后有多少个连通分块. 思路:从后往前操作,从后往前添加i条边等于添加完m条边后删掉前m-i条边,可知刚开始没有边,所以sum[m]=n; #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 100010

hdu 1811Rank of Tetris (并查集 + 拓扑排序)

1 /* 2 题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B. 3 4 现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK". 5 否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出&quo

HDU 1232 畅通工程(并查集)

畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 30485    Accepted Submission(s): 16013 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有

HDU 2017 Code Lock (并查集的应用+快速幂)

链接:HDU 3461 题目大意: 题目的大意是一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限次的"增加"操作后可以变成另一组密码,那么我们认为这两组密码是相同的.该题的目标就是在给定N.M和M个区间的前提下计算有多少种不同的密码. 根据题意,如果一个可调整的区间都没有的话,答案应该是26

HDU 4775 Infinite Go(并查集,模拟)

HDU 4775 Infinite Go 题目链接 题意:围棋,两人轮流走,如果有一链被围死,就会被吃掉,问下完后最后黑色和白色各剩多少棋 思路:模拟,利用一个并查集来保存链,然后并记录下周围有多少个空格,然后去模拟,注意几个点,就是删除的时候,要把空格还回去,还有边界的位置是也算被围死的 代码: #include <stdio.h> #include <string.h> #include <queue> #include <map> using name