HDU 3635-Dragon Balls(高级并查集)

Dragon Balls

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 3242    Accepted Submission(s): 1250

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

好吧 我承认这道题很厉害,题意:T a b 代表将a所在的集合挂在b上,Q a总共询问3个信息:①a所在的集合,(这个很好办,find(a)的返回值就是答案);②a所在的集合中元素的个数,(这个也很容易,用一个size[]数组在合并的时候维护一下就可以了);③a移动的次数,这个就难办了,因为路径压缩会破坏原本的树结构,如果我设一个ttime[]数组,那么需要在路径压缩的时候维护它,比如说 T 1 2, T 1 3

当1和3合并的时候,实际上是fa[2]=3;ttime[2]++;此时ttime[1]仍然等于1,所以当我们查找1时,首先会找的1的祖先是2,这时令ttime[1]+=ttime[2];即向上回溯祖先是,要将转移次数加给子孙。然后会找到2的祖先是3.

感觉这算难一点的并查集吧,不过以前碰到过一个更难的,带权并查集,集合里的每个元素之间互相有关系(就像一张图,两个点之间有权值),那个题至今没做出来。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <list>
using namespace std;
const  int maxn=50100;
const int INF=1<<25;
int fa[maxn],size[maxn],ttime[maxn];
void Make_set(int n)
{
	for(int i=1;i<=n;i++){
		fa[i]=i;
		size[i]=1;
		ttime[i]=0;
	}
}
int Find(int x)
{
	if(x!=fa[x])
	{
		int t=fa[x];
		fa[x]=Find(fa[x]);
		ttime[x]+=ttime[t];//维护ttime数组
		return fa[x];
	}
	return x;
}
void Union(int x,int y)
{
	int fx=Find(x);
	int fy=Find(y);
	if(fx==fy) return ;
	fa[fx]=fy;
	size[fy]+=size[fx];
	ttime[fx]++;
}
int main()
{
	int a,b,T,n,m,cas=1;char c[5];
    scanf("%d",&T);
    while(T--)
	{
		scanf("%d%d",&n,&m);
		printf("Case %d:\n",cas++);
		Make_set(n);
		while(m--)
		{
			scanf("%s",c);
			if(c[0]=='T')
			{
				scanf("%d%d",&a,&b);
				Union(a,b);
			}
			else
			{
				scanf("%d",&a);
				int ans=Find(a);
				printf("%d %d %d\n",ans,size[ans],ttime[a]);
			}
		}
	}
	return 0;
}
时间: 2024-08-28 22:36:51

HDU 3635-Dragon Balls(高级并查集)的相关文章

hdu 3635 Dragon Balls(并查集应用)

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 bal

HDU 3635 Dragon Balls (并查集)

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

HDU 3635 Dragon Balls(并查集--路径压缩拓展应用)

题目大意: 初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城市中. 现在又2种操作: T A B,表示把A球所在城市全部的龙珠全部转移到B城市.(第一次时,因为A球所在的城市只有一个球,所以只移动1个,如果有多个,则全部移动). Q A,表示查询A.要求得到的信息分别是:A现在所在的城市,A所在城市的龙珠数目,A转移到该城市移动的次数(如果没有移动就输出0) 思路:并查集,难点在于求龙珠的转移次数,可以在路径压缩的过程中沿着递归路径累加. //Accepted 1740 KB 5

hdoj 3635 Dragon Balls【并查集求节点转移次数+节点数+某点根节点】

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

HDU 3635 延缓更新的并查集

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

HDU 3635 Dragon Balls 七龙珠 Union Find算法

孙悟空要寻找七龙珠,这回是七龙珠的增强版了,因为这些龙珠会衍生,最后不止七颗龙珠了. 悟空带着布玛的龙珠雷达探测器出发了,却发现布玛的龙珠雷达探测器的程序太垃圾了,所以找到我们这些ACM高手为龙珠雷达探测器写个程序,要求可以显示某颗龙珠所在的城市的位置,该龙珠所在的城市共有多少颗龙珠,龙珠移动过的次数. 布玛是个有钱人啊,写个程序我要价5百万,不算过分吧.因为本程序需要用到Union Find(并查集)算法,而且最困难的部分是如何压缩路径,不压缩路径自然容易做到,要压缩路径可以使得程序加快很多,

HDU 3635 Dragon Balls(带权并查集)

题目地址:HDU 3635 加权并查集水题. 用num数组维护该城市有多少龙珠,用times数组维护每个龙珠运输了多少次.num数组在合并的时候维护.times数组由于每个都不一样,所以要在找根的时候递归来全部维护. 最终,x龙珠所在的城市就是x节点所在的根,x结点所在的跟的num数组值是该城市的龙珠数.times[x]为该龙珠运输了多少次. 代码如下: #include <iostream> #include <cstdio> #include <string> #i

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

HDU 3635 Dragon Balls(并查集)

Dragon Balls Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 64   Accepted Submission(s) : 26 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Five hundred years later

hdu 3635 Dragon Balls(并查集技巧)

题意:n个点m次询问,两种操作:1.将含有龙珠i的集合加入含有龙珠j的集合中:2.查询龙珠i所在堆的编号,龙珠个数,龙珠i的搬运次数: 思路:并查集,数组分别维护关系.数量.搬运次数: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m; int fa[500010],time[500010],num[500010]; void init() { for(