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

作为龙珠的铁杆粉丝,这道题必须A,否则就对不起自己的偶像了。。

题目意思  :

初始时有编号为1-n的龙珠分别放入编号为1-n的城市中,对龙珠有两种操作   输入为T X Y时,即把编号为X的龙珠所在城市里的所有龙珠都移动到编号为Y的龙珠所在的城市。

输入为为Q X 时即查询编号为X的龙珠目前所在的城市编号,所在城市中有多少个龙珠,编号为X的龙珠共移动了多少次。

思路:

很显然是用并查集,题目中这样一句话“ All the dragon balls which are in the same city with A have been transported to the city the Bth ball in. ”,即说明每个城市只能移动一次就成空城了就不能接纳龙珠了,从而可以说明若以土著龙珠(即初始化时就在这个城市里的龙珠)为根结点,那么编号x的龙珠目前所在城市==fiindroot(x)。

城市编号就求出来了。

咱们用一个数组num[i]表示第i座城市里的龙珠数目,那么每次把第j座城市的龙珠移到第i座城市中,第i座城市里龙珠数目为num[i]+=num[j]。

所在城市的龙珠数目也就这么容易的求出了。

比较麻烦的是求编号为X的龙珠的移动次数。

因为移动的龙珠和求的龙珠编号可能不同,若枚举所有龙珠编号则超时。

有一个很巧的方法(我没想出来,看解题报告才知道。。。),咱们用time[i]表示编号为i的龙珠移动的次数,每次需要用到编号i的龙珠的时候,就压缩路径把从i到土著龙珠(根结点)路径上所有结点的time[]都加到time[i]上,因为每次移动都是根结点移动然后再与另外的根结点相合并即整体合并,每次移动都顺带着结点 i 移动,所以从i到根结点所有结点都与结点 i 有顺带关系,用完这些顺带关系即time[i]已求出后就舍弃这些中间点,使 i 指向新的根结点从而保证用过的顺带关系不会重复使用。

是不是有些一头雾水呢?  其实我刚开始看的时候也是这样。。没关系,贴出代码,自己弄几个例子调试跟踪下就懂了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6
 7
 8 int father[10005];
 9 int timee[10005];
10 int num[10005];
11
12 int findroot(int p){
13     if(p==father[p]) return p;
14     int f=father[p];
15     father[p]=findroot(father[p]);
16     timee[p]+=timee[f];   //把沿途上所有与点p有顺带关系的点的移动次数加到点p上 (好好调试跟踪下)
17     return father[p];
18 }
19
20 void unsion(int x,int y){
21     int fx=findroot(x);
22     int fy=findroot(y);
23     if(fx!=fy){                   //每次都以新的土著龙珠为根结点
24         num[fy]+=num[fx];
25         father[fx]=fy;
26         timee[fx]=1;
27     }
28 }
29
30 main()
31 {
32     int t, i, j, x, y,     n, Q, kase=1;
33     char s[10];
34     cin>>t;
35     while(t--){
36         scanf("%d %d",&n,&Q);
37         printf("Case %d:\n",kase++);
38         for(i=1;i<=n;i++){
39             father[i]=i;
40             timee[i]=0;
41             num[i]=1;
42         }
43         while(Q--){
44             scanf("%s",s);
45             if(strcmp(s,"T")==0){
46                 scanf("%d %d",&x,&y);
47                 unsion(x,y);
48             }
49             else {
50                 scanf("%d",&x);
51                 int fx=findroot(x);
52                 printf("%d %d %d\n",fx,num[fx],timee[x]);
53             }
54         }
55     }
56 }

HDU 3635 延缓更新的并查集,布布扣,bubuko.com

时间: 2024-08-24 21:20:01

HDU 3635 延缓更新的并查集的相关文章

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(并查集--路径压缩拓展应用)

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

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 3461 Code Lock(并查集的应用+快速幂)

* 65536kb,只能开到1.76*10^7大小的数组.而题目的N取到了10^7,我开始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 其实路径压缩也可以不用.............  题目的大意: 一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限

HDU 1558 Segment set (并查集+线段非规范相交)

题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. 1 //1558 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 #define eps 1e-8 7 #define zero(x) (((x) > 0 ? (x) : (-x)) < e

HDU 3407.Zjnu Stadium 加权并查集

Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3726    Accepted Submission(s): 1415 Problem Description In 12th Zhejiang College Students Games 2007, there was a new stadium built

HDU 1213 How Many Tables (并查集)

How Many Tables Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1213 Appoint description:  System Crawler  (2015-05-25) Description Today is Ignatius' birthday. He invites a lot of friends. Now

hdu 1232 畅通工程(并查集算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232 畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31088    Accepted Submission(s): 16354 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条

HDU 3371 Connect the Cities(并查集+Kruskal)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 思路: 这道题很明显是一道最小生成树的题目,有点意思的是,它事先已经让几个点联通了.正是因为它先联通了几个点,所以为了判断连通性 很容易想到用并查集+kruskal. 不过要注意 这题有一个坑点,就是边数很多 上限是25000,排序的话可能就超时了.而点数则比较少 上限是500,所以很多人选择用Prim做.但我个人觉得这样连通性不好判断.其实边数多没关系,我们主要去重就好啦,用邻接矩阵存下两点