(hdu step 5.1.5)Dragon Balls(求并查集的根节点、节点数和个结点的移动次数)


题目:

Dragon Balls

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 562 Accepted Submission(s): 239
 
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
 
Author
possessor WC
 
Source
2010 ACM-ICPC Multi-University Training Contest(19)——Host by HDU
 
Recommend
lcy



题目大意:

起初球i是被放在i号城市的,在年代更迭,世事变迁的情况下,球被转移了,而且转移的时候,连带该城市的所有球都被移动了:T A B(A球所在的城市的所有球都被移动到了B球所在的城市),Q A(问:A球在那城市?A球所在城市有多少个球呢?A球被转移了多少次呢?)。


题目分析:

                 并查集。求并查集的根节点、节点数和每个节点的移动次数。需要注意的是求每个节点的移动次数。如果在

合并的时候进行一次暴力来求移动次数的话,会TLE,所以在这里是在路径压缩时求每个节点的移动次数。

T a b 表示将索引为a的龙珠所在城市的所有龙珠移到索引为b的龙珠的所在城市

Q a 。查询以下数据:a龙珠所在城市的索引、a龙珠所在城市的龙珠数、a龙珠移动的次数


代码如下:

/*
 * e.cpp
 *
 *  Created on: 2015年3月2日
 *      Author: Administrator
 */

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 10001;
int father[maxn];
int nums[maxn];
int move[maxn];

int n;

void init(){
	int i;
	for(i = 1 ; i < maxn ; ++i){
		father[i] = i;
		nums[i] = 1;
		move[i] = 0;
	}
}

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

	//利用路径压缩来求结点的移动次数
	int temp = father[a];
	father[a] = find(father[a]);//不要和下面一行代码位置调换了.会WA的
	move[a] += move[temp];//每个节点的移动次数=自己的移动次数+父亲节点的移动次数


	return father[a];
}

void join(int a,int b){
	int fa = find(a);
	int fb = find(b);

	if(fa != fb){
		father[fa] = fb;
		nums[fb] += nums[fa];//求并查集的节点数的关键代码

		move[fa] = 1;

	}
}


int main(){
	int t;
	scanf("%d",&t);
	int k;
	for(k = 1 ; k <= t ; ++k){
		printf("Case %d:\n",k);

		init();

//		int n;
		int q;
		scanf("%d%d",&n,&q);

//		string str;
		char str[2];

		int i;
		for(i = 1 ; i <= q ; ++i){
//			cin >> str;//输入的数据规模较大,不要使用cin,否则会TLE
			scanf("%s",str);

			if(str[0] == ‘T‘){
				int a,b;
				scanf("%d%d",&a,&b);
				join(a,b);
			}else if(str[0] == ‘Q‘){
				int a;
				scanf("%d",&a);

				printf("%d %d %d\n",find(a),nums[find(a)],move[a]);
			}
		}
	}

	return 0;
}










郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。