对于一个有n个结点的无根树,找一个点作为根,使得最大子树的结点数最小,换句话说,删除这个点后最大连通块的结点数最小。
任选一个点作为根,设d(i)表示以i为根的子树的结点个数,那么:
只需要一次dfs,连记忆化都不需要,因为没有重复计算。现在重点来了:
删除结点i之后,最大连通块有多少个结点呢?
结点i的子树中最大的有max{d(j)}个结点,i的“上方子树”中有n-d(i)个结点!po...
分类:
其他好文 时间:
2016-05-07 10:33:35
阅读次数:
112
求树的重心,直接当模板吧。先看POJ题目就知道重心什么意思了。。。 重心:删除该节点后最大连通块的节点数目最小 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 #include<stack ...
分类:
其他好文 时间:
2016-04-15 00:04:18
阅读次数:
165
树的点分治 首先找树的重心,把根节点设为树的重心。然后进行点分治(就是从根开始,看经过根的方案数,在把根删掉,求每棵子树)。
分类:
其他好文 时间:
2016-03-20 19:43:20
阅读次数:
141
处理处每个节点的孩子有几个,和树的大小就好了。 #include<cstdio> #include<queue> #include<cstring> #include<iostream> #include<algorithm> #define INF 99999999 using namespace
分类:
其他好文 时间:
2016-02-28 12:29:59
阅读次数:
117
说白了就是树形dp嘛。。。用来解决树上路径点权统计问题。=>1,先找出整颗树的重心,YY一下;=>2.转化成有根树;=>3.求出经过根节点的两点之间距离;=>4.在子树中用同样的方法处理;=>然后就好了,累不想写
分类:
其他好文 时间:
2016-01-15 23:06:26
阅读次数:
137
可以说是点分治第一题,之前那道的点分治只是模模糊糊,做完这道题感觉清楚了很多,点分治可以理解为每次树的重心(这样会把数分为若干棵子树,子树大小为log级别),然后统计包含重心的整个子树的值减去各个子树的值,这样算出的就是与这个重心有关的情况的答案,比如这道题,求路径,那么就考虑在重心所在的子树中所有...
分类:
其他好文 时间:
2015-12-31 07:15:29
阅读次数:
149
首先考虑暴力,可以枚举每两个点求lca进行计算,复杂度O(n^3logn),再考虑如果枚举每个点作为lca去枚举这个点的子树中的点复杂度会大幅下降,如果我们将每个点递归考虑,每次计算过这个点就把这个点删掉,那么如果每次删掉的点是当前子树的重心,枚举点对的复杂度就只有O(logn),对于每次查询答案在...
分类:
其他好文 时间:
2015-12-31 07:13:35
阅读次数:
177
传统的树分治,不能处理在线的询问。我们可以把每次点分治的重心和它分割出的子树的重心连接,容易发现形成了一颗新的树。这棵树有哪些性质呢?首先,树高不超过log(n),其次,一个节点原子树中的所有节点,依然在新树里它的子树中。因为树高只有log(n),所以我们考虑从一个点出发的路径时,可以枚举它到新树中...
分类:
其他好文 时间:
2015-12-30 13:42:10
阅读次数:
150
题目大意:给定n个节点组成的树,树有边权,现在给定一个点u和v,dis(u,v)表示u和v节点的最近距离,问dis(u,v)<=k的uv对数,n <= 1万,k不定,权值<=1000。orz看着代码理解,先求出树的重心(还是质心?),避免树成了一条链使得算法退化。把无根树转成有根树。然后求出距离根节...
分类:
其他好文 时间:
2015-12-15 22:48:19
阅读次数:
185