博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU-3635 Dragon Balls
阅读量:4123 次
发布时间:2019-05-25

本文共 2412 字,大约阅读时间需要 8 分钟。

#include 
using namespace std;const int n_max = 1e4 + 5;struct node{ int root; int leaf; int transfer;} ball[n_max];int t, n, q;int Find(int x){ if(x == ball[x].root) return x; else { int temp = ball[x].root; //记录原根节点 ball[x].root = Find(ball[x].root); //路径压缩 根节点改变 ball[x].transfer += ball[temp].transfer; //因为是原根节点移动,所以 以 原根节点的移动 带动改 此时查询的节点的移动次数 return ball[x].root; }}void Merge(int x, int y){ x = Find(ball[x].root); y = Find(ball[y].root); if(x != y) { ball[x].root = y; //改变根节点 ball[x].transfer ++; //根节点移动 (Find函数中的temp) ball[y].leaf += ball[x].leaf; //节点数量移动 ball[x].leaf = 0; //全移走 归0 }}int main(){ scanf("%d", & t); int cas = 0; while(t --) { printf("Case %d:\n", ++ cas); scanf("%d %d", & n, & q); for(int i = 1; i <= n; i ++) //初始化 { ball[i].root = i; ball[i].leaf = 1; ball[i].transfer = 0; } char operation; for(int i = 1; i <= q; i ++) { getchar(); scanf("%c", & operation); int a, b; if(operation == 'T') { scanf("%d %d", & a, & b); Merge(a, b); } else if(operation == 'Q') { scanf("%d", & a); int parent = Find(a); //其实我觉得这蛮关键的 这一次调用函数Find,使整个并查集的结构更分明,只有一个根节点,其他所有节点的root都等于根节点,并且a的最后一次transfer是在这里调用累加的(没有这一步操作是不行的) printf("%d %d %d\n", parent, ball[parent].leaf, ball[a].transfer); //输出根节点,根节点的节点数,a的转移次数 } } }}

(摘自飘过的小牛)

初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城市中。

现在又2种操作:

T A B,表示把A球所在城市全部的龙珠全部转移到B城市。(第一次时,因为A球所在的城市只有一个球,所以只移动1个,如果有多个,则全部移动)。

Q A,表示查询A。要求得到的信息分别是:A现在所在的城市,A所在城市的龙珠数目,A转移到该城市移动的次数(如果没有移动就输出0)

题解:
(参考 飘过的小牛)我也是超时的问题…也知道该在Find函数中改..不过不知道该怎么改。后来看到了大神…我模拟了好几遍,也终于弄懂,不过不知道能不能日后想的起并运用..这道并查集我觉得是比较全面的。
Find函数 所做的操作 是 将 所有的节点 指向 根节点。
Merge函数 所做的操作 是 将Find出来的根节点 指向 另一个节点,使这个节点成为一个新的根节点。
举例 : 此时的数组结果应该是这样… 3 3 4 4!(下标分别 为 1 2 3 4)(Merge函数中的 Find的操作结果 是 将 下标为 1 2 的值改为了 3 3,Merge的最后操作是 将 下标为 3 的值 改为 4)(下标为 4 的值 本来就为 4,不变)
上面AC代码中 最后一次的 Find (例如Find(1))作用后,数组的结果 : 4 3 4 4(最后一次压缩路径 将Find的子节点指向根节点).
这里写图片描述

瞎比画了两幅图:

第一幅(Merge函数):
1 –> 3 (或者 2 –> 3): Merge函数中 Find函数 的调用,查找 1 或者 2 的根节点。再将 此根节点 指向 4。这样, 1 和 2 通过 3 间接地 指向 根节点4.
第二幅(AC代码中 最后一个Find函数):
压缩路径,使Find的子节点指向根节点。

你可能感兴趣的文章
VUe+webpack构建单页router应用(一)
查看>>
Node.js-模块和包
查看>>
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
PHP 7 的五大新特性
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
OpenCV meanshift目标跟踪总结
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
如果你还不了解 RTC,那我强烈建议你看看这个!
查看>>
沙雕程序员在无聊的时候,都搞出了哪些好玩的小玩意...
查看>>
Mysql复制表以及复制数据库
查看>>
Linux下SVN客户端使用教程
查看>>
Linux分区方案
查看>>
如何使用 systemd 中的定时器
查看>>
git命令速查表
查看>>
linux进程监控和自动重启的简单实现
查看>>
OpenFeign学习(三):OpenFeign配置生成代理对象
查看>>