您的位置:首页 > 编程语言 > Go语言

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

2015-03-04 10:27 302 查看
题目:

Dragon Balls

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 562 Accepted Submission(s): 239
 
[align=left]Problem Description[/align]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. 
[align=left]Input[/align]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) 
[align=left]Output[/align]
            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. 
[align=left]Sample Input[/align]
2
3 3
T 1 2
T 3 2
Q 2
3 4
T 1 2
Q 1
T 1 3
Q 1
 
[align=left]Sample Output[/align]
Case 1:
2 3 0
Case 2:
2 2 1
3 3 2
 
[align=left]Author[/align]possessor WC 
[align=left]Source[/align]2010 ACM-ICPC Multi-University Training Contest(19)——Host by HDU 
[align=left]Recommend[/align]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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: