题目链接:http://poj.org/problem?id=1741
给定一颗树,以及k,一次询问,找出所有路径长度小于等于k的点对数。
前置:flag[]数组表示删除的点,d[]数组代表节点到根节点的距离,b[]数组代表节点属于哪一颗子树,a[]子树中所有的节点(并按照d从小到大排序),size1[]数组表示编号为i的子树的大小,cnt[]数组表示编号为i的子树出现的次数。
首先我们先选择一个点作为树根,将无根树转换为有根树,树根为p,那么节点x与节点y之间的路径就有两种情况:
如图是一颗树,第一次选取了1作为重心,将树划分成绿色的三部分,那么第一种路径就是2节点所在的块的点与3节点所在的块的点之间存在的点对数。
对于第二种路径,我们对2子树进行划分,类似第一次那种的划分,将子树分为了红色的四部分,其中2是该子树的重心,然后计算该子树中以2为树根的第一种路径的个数,接下来的划分也是同理。
于是通过这种方法将第二种路径转换为第一种路径求解即可。
即第一种路径的计算是由属于不同连通块的点之间得来,第二种路径的计算是将一个连通块通过划分转换为有根树求解。
- 经过树根的,那么x->y的路径可看做:x->p,p->y的路径和,那么这种情况下,可以预处理所有的点到树根的距离即可