这道题说,在很久很久以前,有一个故事。故事的名字叫龙珠。后来,龙珠不知道出了什么问题,从7个变成了n个。

在悟空所在的国家里有n个城市,每个城市有1个龙珠,第i个城市有第i个龙珠。

然后,每经过一段时间,城市i的所有的龙珠都会被转移到城市j中。

现在有两种操作:

1. T A B,表示将A龙珠所在城市的所有龙珠全部转移到B龙珠所在城市去。

2. Q A,表示询问A龙珠所在的城市X,以及X城市有几个龙珠,A龙珠被转移了几次。

输入:

第一行输入1个整型数字t,表示一共t组测试样例。

接下来,每组样例第一行包含2个整型数字n,m,表示共有n个城市,m次操作。

操作有T A B,以及Q A两种,具体含义看上面。

输出:

当输入Q A时,输出所询问的数据。每次输出占一行。

说实话,我写这道题的时候,感觉这道题相当有问题。

因为我做不出来,所以依然可耻地看了题解。但是题解中居然是用了并查集!

并查集是有问题的。因为在T A B时,它的含义是龙珠A移动到龙珠B那里,也就是说,之后的T B A 是没有意义的。但实际上,如果是按照城市A的龙珠转移到城市B去,那么实际上之后再进行T B A是有意义的。所以,是不能使用并查集的。

后来我发现我读错题了……

所以,你可以忽略以上六行的文字,包括这一行。

分析:

正确理解了题意以后,发现这是一道加权并查集。而且每个节点有两个权值。一个是所在城市的龙珠数量sum[],一个是移动次数mv[]。

所以可以开3个数组。然后注意一下每个数据的计算方式就行了。

初始化时,每个龙珠的父节点是自己,所在城市的龙珠数量为1,移动次数为0。

接下来,每移动一次,所移动的龙珠集合的根节点的移动次数从0变成1,其它龙珠的移动次数依次变成他的父节点的移动次数+自己的移动次数,即mv[x] = mv[fx]+mv[x](这一句不理解不要紧,自己在纸上推一下,注意路径压缩)。 而且是递归修改,从根节点开始修改,然后是以根节点为父节点的节点,然后是依次递归回溯。这样可以在我们用到某个节点的时候,一次将这个节点更新成功,而如果每次修改时都更改所有被修改的节点,那么许多节点都会被修改多次。这样,所必须的修改就是将被合并的根节点修改一次即可。

具体见代码——

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; const int N = ; int n, m, t;
int sum[N], fm[N], mv[N]; //分别表示龙珠所在地的龙珠数量和,某龙珠的父节点,某龙珠被移动的次数
int a, b;
char s[]; void init()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) //初始化
{
fm[i] = i;
sum[i] = ;
mv[i] = ;
}
} int mfind(int x) //合并与查询时都使用
{
if(x == fm[x]) return x;
int fx = fm[x];
fm[x] = mfind(fm[x]);
mv[x] += mv[fx]; //关键点,龙珠x被移动的次数
return fm[x];
} void mmerge(int x, int y)
{
int fx = mfind(x);
int fy = mfind(y);
if(fx != fy)
{
fm[fx] = fy;
sum[fy] += sum[fx]; //计算龙珠fy处的龙珠总和
mv[fx] = ; //根节点首次被移动,所以移动次数为1
}
} void work()
{
while(m--)
{
scanf("%s", s);
if(s[] == 'Q')
{
scanf("%d", &a);
int fa = mfind(a);
printf("%d %d %d\n", fa, sum[fa], mv[a]);
}
else if(s[] == 'T')
{
scanf("%d%d", &a, &b);
mmerge(a, b);
}
}
} int main()
{
//freopen("test.in", "r", stdin);
while(~scanf("%d", &t))
{
for(int tm = ; tm <= t; tm++)
{
init();
printf("Case %d:\n", tm);
work();
}
}
}

hdu 3635 Dragon Balls(加权并查集)2010 ACM-ICPC Multi-University Training Contest(19)的更多相关文章

  1. hdu 3635 Dragon Balls(并查集应用)

    Problem Description Five hundred years later, the number of dragon balls will increase unexpectedly, ...

  2. hdu 3635 Dragon Balls(并查集)

    题意: N个城市,每个城市有一个龙珠. 两个操作: 1.T A B:A城市的所有龙珠转移到B城市. 2.Q A:输出第A颗龙珠所在的城市,这个城市里所有的龙珠个数,第A颗龙珠总共到目前为止被转移了多少 ...

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

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  4. HDU 3407.Zjnu Stadium 加权并查集

    Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. hdu 3635 Dragon Balls(并查集)

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. hdu 3635 Dragon Balls (带权并查集)

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. HDU 3635 Dragon Balls(超级经典的带权并查集!!!新手入门)

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. HDU 3635:Dragon Balls(并查集)

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  9. [HDOJ3635]Dragon Balls(并查集,路径压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3635 题意:有n个龙珠,n个城市.初始状态第i个龙珠在第i个城市里.接下来有两个操作: T A B:把 ...

随机推荐

  1. POJ 1733 Parity game(离散化+带权并查集)

    离散化+带权并查集 题意:长度为n的0和1组成的字符串,然后问第L和R位置之间有奇数个1还是偶数个1. 根据这些回答, 判断第几个是错误(和之前有矛盾)的. 思路:此题同HDU 3038 差不多,询问 ...

  2. java基础知识回顾之javaIO类--File类应用:获取指定目录下面的指定扩展名的文件,将文件的绝对路径写入到目的文件当中

    /** * File文件综合应用 * 需求:获取指定目录下面,指定扩展名的文件,将文件的绝对路径写到文本文件当中. *  * 思路:1.需要深度遍历.--递归 * 2.遍历的过程中过滤指定扩展名的文件 ...

  3. 如何正确学习JavaScript

    不要这样学习JavaScript 不要一开始就埋头在成堆的JavaScript在线教程里 ,这是最糟糕的学习方法.或许在看过无数个教程后会有点成效,但这样不分层次结构地学习一个东西实在是十分低效,在实 ...

  4. QAQ高精度模板笔记√

    #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #i ...

  5. Protege汉字不能正常显示问题

    在Protege5.0中有下面的问题: 点击uses,汉字不能正常显示. 在qq群里面问到,可以通过设置label的方式,在对类,子类命名成英语的,点击annotations,在label中设置汉字名 ...

  6. 欧拉工程第60题:Prime pair sets

    题目链接 五个数,任意两个数的任意链接后的数还是质数 满足这个条件的最小五个数的和是多少? 结果:26033 纯暴力破解: package projecteuler51to60; import jav ...

  7. SQLite操作(C# )

    C#连接SQLite的...方法 http://www.cnblogs.com/virusswb/archive/2010/09/17/SQLite1.html 1 SQLite简介 SQLite,是 ...

  8. Eclipse:快捷

    Ctrl +单击方法------------查看方法 ALT+/    -------------代码助手 Ctrl+O   -------------列出方法和成员变量或布局结构 Ctrl+D   ...

  9. WCF入门(十二)---WCF异常处理

    WCF服务开发者可能会遇到需要以适当的方式向客户端报告一些不可预见的错误.这样的错误,称为异常,通常是通过使用try/catch块来处理,但同样,这是非常具体的技术. 由于客户端的关注领域不是关于如何 ...

  10. 配置Excel的DCOM权限

    异常详细信息: System.UnauthorizedAccessException: 检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-00000000004 ...