HDOJ-3635-Dragon Balls 解题报告

<知识分享>

这是一道考察并查集的路径压缩的题。题意:在悟空的世界,有N个龙珠和N个城市(编号从1到N),神龙最开始把每颗龙珠都放在对应编号的城市。悟空要去收集龙珠,但是这些龙珠有时候是会被转移的。你需要告诉悟空一些有关龙珠的信息才行。现在又T组测试,每组测试都有一个N(龙珠和城市的数量)和Q(操作行为的数量),操作行为有两种:

T A B,将编号为A的龙珠所在城市的所有龙珠转移到编号为B的龙珠所在的城市,两个城市不同

Q A,悟空要知道X(龙珠A所在城市的编号),Y(编号为X的城市里的龙珠数)以及Z(编号为A的龙珠转移的次数)

解题思路:首先根据每个龙珠的编号我们都需要知道3个信息,所在城市的编号,所在城市的龙珠数以及该龙珠被转移过的次数。首先我们分析一下T操作,首先两个城市一定不相同,那么将所有龙珠都移动到另一个城市时,肯定有一个龙珠本来就在那个城市且一次都没有被移动过,这个龙珠就是根节点。那么同理,根节点龙珠肯定从来没被移动过而且不会出现把这个城市的所有龙珠全部移动到空城市这种情况。有了这样的规律,我们可以通过维护根节点所在城市龙珠数来查找这个城市每个龙珠的X和Y。至于Z,路径压缩时我们要把对应节点压缩到根节点之下,对应的Z也要进行同步更新,每次移动时我们只将被移动的城市的根节点的移动次数+1,那么当路径压缩时沿途节点的移动次数之和(当然也包括待压缩节点本身)就是这个节点真正的被移动次数。

接下来是解题代码:


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 10001
  4. int bleg[N];    //存储当前节点的父节点
  5. int tran[N];    //存储被移动的次数
  6. int city[N];    //存储所在的城市
  7. int bnum[N];    //存储在同一地点的龙珠总数
  8. int t;
  9. int n, m;
  10. void Init();            //初始化
  11. int Find(int x);                //并查集查找
  12. void Union(int x, int y);       //并查集合并,也就是T操作
  13. void Q(int x);
  14. int main()
  15. {
  16. int tn = 1;
  17. int i, a, b;
  18. char ch;
  19. scanf("%d", &t);
  20. while (t--)
  21. {
  22. scanf("%d %d", &n, &m);
  23. Init();
  24. printf("Case %d:\n", tn++);
  25. for (i=0; i<m; ++i)
  26. {
  27. scanf(" %c", &ch);
  28. if (ch == ‘T‘)
  29. {
  30. scanf("%d %d", &a, &b);
  31. Union(a, b);
  32. }
  33. else
  34. {
  35. scanf("%d", &a);
  36. Q(a);
  37. }
  38. }
  39. }
  40. return 0;
  41. }
  42. void Init()            //初始化
  43. {
  44. int i;
  45. for (i=1; i<=n; ++i)
  46. {
  47. bleg[i] = city[i] = i;      //初始化父节点和所在城市
  48. tran[i] = 0;
  49. bnum[i] = 1;
  50. }
  51. return;
  52. }
  53. int Find(int x)                  //并查集查找
  54. {
  55. int y = x;
  56. int z;
  57. int ntran = 0;
  58. while (y != bleg[y])
  59. {
  60. ntran += tran[y];   //存储沿途节点的被移动次数总和
  61. y = bleg[y];
  62. }
  63. while (x != bleg[x])
  64. {
  65. z = bleg[x];
  66. ntran -= tran[x];   //为下个节点更新移动次数做准备
  67. bleg[x] = y;        //压缩到根节点之下
  68. tran[x] += ntran;   //移动次数同步更新
  69. x = z;
  70. }
  71. return y;
  72. }
  73. void Union(int x, int y)       //并查集合并,也就是T操作
  74. {
  75. int fx = Find(x);
  76. int fy = Find(y);
  77. bleg[fx] = fy;
  78. ++tran[fx];                 //被移动的根节点的被移动次数加1
  79. bnum[fy] += bnum[fx];       //更新城市龙珠数
  80. return;
  81. }
  82. void Q(int x)
  83. {
  84. int fx = Find(x);
  85. printf("%d %d %d\n", city[fx], bnum[fx], tran[x]);
  86. return;
  87. }

HDOJ-3635-Dragon Balls 解题报告,布布扣,bubuko.com

时间: 2024-08-07 01:36:44

HDOJ-3635-Dragon Balls 解题报告的相关文章

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

hdoj 3635 Dragon Balls

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

HDU 3635 Dragon Balls 七龙珠 Union Find算法

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

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(并查集)

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(并查集应用)

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): 3461    Accepted Submission(s): 1348 Problem Description Five hundred years later, the number of dragon balls will increase unexpect

HDOJ 3547 DIY Cube 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3547 题目大意:求用$C$种颜色给立方体的8个顶点染色的本质不同的方法.两种方法本质不同即不能通过旋转立方体使得两个立方体的染色情况一致. 简要题解:首先可以得到有24种组合旋转方式.根据Polya定理以及群论中的拉格朗日定理,然后再自己多想一想,就可以得到:$Ans=\frac{x^8+Ax^4+Bx^2+Cx}{24}$,可知有3个未知数,然后样例正好有3组数据,所以可以解方程解得$A=17,B

HDU 3635 Dragon Balls(带权并查集)

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