[原创]POJ 1741 Tree [点分治入门题]【分治】
[原创]POJ 1741 Tree [点分治入门题]【分治】
2017-07-17 20:37:58 Tabris_ 阅读数:375
博客爬取于2020-06-14 22:39:38
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75267826
题目链接:http://poj.org/problem?id=1741
——————————————————————————————————————————
Tree
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 22808 Accepted: 7542
Description
Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
Input
The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.
Output
For each test case output the answer on a single line.
Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
Sample Output
8
——————————————————————————————————————————
题目大意:
给你一棵树,问你两点间距离不超过k的点对个数
最好去看论文===>戳这里
考虑到每颗树上 统计路径经过树根的点对,
很容易想到 处理一遍子树 记录每个节点到达根节点的距离,
然后就变成了
给定一个序列,统计两个数加和不超过k的数对的个数
尺取法就能做了
但是注意这里计算之后会有重复的情况
比如当前计算的是根为1 的情况 这个时候如果k比较大 那么还会把<4,6>的情况 给计算上,但是<4,6>的路径是 4->5->6
所以我们还需要减去以1的儿子节点为根的时候的情况
并不断递归下去找一颗颗子树.
但是这样下去的话 能发现 不断递归下去的话
复杂度依赖于 树的形态
如果树是严格平衡的话递归下去的复杂读就是
如果树的形态是一条链的情况 就会变成
于是这里 采取树的重心 作为树根,这样下去的话 能保证 递归下去的深度最低 最终做到复杂度O [证明请移步国家队论文↑]
注意: 对于 递归下去的子树 为了保证复杂读 也要再次采用重心为根来做,
于是最终复杂度就变为
其中一个 为分治 向下递归的复杂度
另一个 为统计的时候 需要保证序列单调的 排序复杂度
附本题代码
——————————————————————————————————————————
1 | # include <stdio.h> |