今日之趣题

本文介绍了一道结合并查集与树结构的算法题解析,通过自底向上的方式计算特定节点为根的子树节点数量,巧妙地运用了拓扑排序思想。

这是今天考的PAT中的一道题目,虽然考的很差啦。但是整体题目记不住了。只记得了一个大致的框架。哪个时候能再遇到这个题目再把这个具体的、超级长的题目搬过来。

整个题目抽象一点点说是人际关系的。题目是利用并查集的思想去构造——即每个结点存储的是它的父节点的值,根结点的父节点是它自己。根结点始终唯一,就是第一个结点。

给定输入数据

首先给出n,啥的
所有的这些从1到n编号。n属于[2,100000]。
然后给出一些结点的下标,要求你去找出这个圈子里有多少人。这个圈子里的人从这个人往下开始算。他后面的所有人和他自己都算到这个圈子里面。

解题过程

最开始看完题目觉得和并查集有关。就一边敲并查集的两个函数,边想怎么利用并查集的性质去构造。
在读取数据的时候,发现根据我的方法去读,数据是错的。
然后看它给出的那个图示,也没有看懂。
只好再去读一下题目。
后来发现它第一个数据因为是默认是根,所以它的数据根本就没给,我多读了一个元素,汗。
之后就是看它那个要求输出的东西,第一次看是真心没看懂。不仅是英文绕,更是不懂它的那个unit和group想表达什么。后来才突然发现,
这就是要你去计算以当前结点为根结点的树的结点个数。
但是这个题很恶心的就是它是倒过来的,不是正着的,算的就很烦。
当时是打算遍历n2次,去硬算出有多少个结点。
但是突然制止住自己了,觉得太不优美了。于是认真想想了,觉得思路错了,应该自底向上。
从叶子结点到根结点。
从每个结点的孩子推它有多少个结点。
然后从底层的叶子结点开始。
然后就想什么是叶子结点。
哦,是那些不是别人的父节点的结点。
于是我就定义了一个visit数组,去找出叶子结点。
之后就遍历一遍数组,把叶节点的父节点标记过没有被访问过。
然后打算再去这样做几次,一直到最上层的根。
但是当时脑子又糊涂了,不知道怎么去知道需要循环几次。
突然又想到,如果所有的都找完了,根结点就被访问了。
如果根结点被访问了,那么肯定是遍历完了。
当时犯了一个错误,把i当成1。i 1 傻傻分不清 。看了5分钟才发现。
之后总感觉算的不对劲,就是有的结点又不是只有一个孩子啊。
突然开窍了,脑中浮现了一个词-indegree。
然后把visit数组的 = 1换成了++;
然后稍微调整了一下,全过了。

总结

其实这道题结合了用并查集结合上了树,然后将求树的结点个数和拓扑排序结合起来。知识点结合的挺好的。感觉这题还挺有意思的写的。
鉴于明天要做早8人,现在先暂且打住吧。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值