posts - 10,  comments - 14,  trackbacks - 0
re: poj 1182 解题报告 tortoisewu 2009-05-30 22:28
建议你画个图理解下会容易很多。
先说下合并函数中的关系,因为在合并函数之前先进行了查找函数,而在查找函数中已压缩了路径,即把查找的点到根结点路径上所有点都挂到了根结点下,并更新了它们kind的值,保证kind值是正确的(在这之前是不正确的);所以在合并函数中x,y,rootx,rooty的kind值在它们原先的集合中都是正确的,在合并时,要将rooty挂到rootx上,并只更新rooty的kind值以保证rooty在新的集合中kind值正确,而不必管rooty原先集合的其它结点kind值(没法管,因为并查集只能从叶节点遍历到根结点,无法向下遍历,将会放到find函数中更新)。更新的依据是三个关系:x和y的关系,x和rootx关系,y和rooty关系;对于这题就一定能得到rootx和rooty的关系,以更新对rooty在新的集合中的kind值。
如果你能理解了合并函数,那查找函数便可以推得,因为我们合并时只更新了挂在根结点上的原先集合根结点的kind值,所以这里要把查找路径上所有的点先挂到根结点上,并更新其kind值(也就是每个集合深度为1的结点的kind值都是正确的)。更新顺序一定要是从深度低的到深度高的,因为更新依据要依赖当前结点的原kind值和其父节点的更新后的kind值。为什么是上述给出的两个值的和的关系呢?因为在合并前根结点的kind都为0,所以合并后原被合并集合深度为1的点的kind值只要加上更新后原其根结点的kind值就能得到正确关系了。一定要画图理解,模拟下过程,结合我红色标识的三个式子一起理解。我还有篇总结也许有帮助http://www.cppblog.com/tortoisewu/archive/2009/05/29/86110.html@whr
<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(1)

随笔档案

文章分类

搜索

  •  

最新评论

阅读排行榜

评论排行榜