爱学习受.NET

www.icjyw.com 记录开发技术收藏天地
公告信息
www.icjyw.com 记录开发技术收藏天地
文章分类
文章档案
文章
pku 1986 LCA算法的应用技术发展
2011/8/2 14:28:39

题目大意是在一棵树中,通过提问的方式找出任意两点间的最短距离。对每颗树的提问次数可高达1W次。

分析:

此题高达4W多个点,4W多条边,还有如此高的提问次数,针对题目次数这么多,我们容易想到将每两个点的距离都找出来,以后你问一个我直接作答。

而且更容易想到的是floyd算法,可是我们注意到节点高达4W。肯定超时!

我们要注意这是一棵树,在一棵树中,两个节点通过公共祖先而互达的那条边一定是最短的。那么问题便转化为了求公共祖先。

利用LCA的离线tarjan算法,我们可以轻松的找到任意两点间的祖先,同时在深度遍历的同时,记录所有点到root的距离。最后我们只要输出

该两点离root的距离之和减去两倍的祖先到root的距离,也即:dist[a]+dist[b]-2*dist[lca(a,b)];

还有,该题是通过提问的方式来考察,我们不可能每次都运用tarjan算法找祖先,我们只有把所有问题制成链表,在第一次tarjan中便找出所有问题的祖先节点。

tarjan中,找到某两点的祖先的依据是,当前已遍历到了其中一个点,并且另一个点早也被遍历过,那么沿着任意一个节点往回找,便可以找到祖先。

证明:因为我们对每一个节点开始进行遍历的时候,都是将它做为一个独立的集合来处理,它和它所有的子孙都将被加入这个集合,这所有的都处理完之后,最后我们再决定该集合将属于谁。而我们通过该两点找祖先的事件是发生在该集合合并给其他集合之前,也就是说,他们的祖先节点的pre[x]一定是等于x的!

引自:http://pdflist.mmic.net.cn

新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"
 MyQBlog   浏览(2579)   评论(0)   关键字
  
Copyright © 2010-2020 power by CYQ.Blog - 秋色园 v2.0 All Rights Reserved