?
题意:给出一棵树,节点数为N(N<=10000),给出N-1条边的两点和权值,给出数值k,问树上两点最短距离小于k的点对有多少个。
思路:拿到题的第一反应是LCA问题,不过细一想询问次数极限情况可以达到10000*5000次,即使用Tarjan也是超时没商量的。
2009年国家队论文提供了树的分治思想,对于本题就是树的分治的点分治的应用。每次找到能使含节点最多的子树的节点最少的根分而治之,同样方式分别处理它的所有子树,知道处理到单独的节点。这样可以使复杂度最低化。(具体找根的方式和上一题思想类似,传送门:http://blog.csdn.net/ooooooooe/article/details/38981129 )
对于每个根,记录其他点到根的距离,我要找出它的两个子节点分别处于它的不同子树并且距离小于k的情况数,不记录在同一子树的情况是因为对于同一子树的两个节点,它们的最短距离并不是它们到根的距离之和,而且如果对于每个根都记录处于相同子树的节点,那么会记重复情况。具体处理的方式是先记录到根距离之和小于等于k的点对的数量,然后对于每个子树分别除去在子树中到根距离之和小于等于k的点对的数量。
?
代码:
?
#include
#include
#include
#include
#include
#include
#include
#include
#include