树分治之点分治模板总结
点分治的时间复杂度为O(NlogN)。 由于每次都是找重心,所以处理完一个大小为N的树后,每个子树的大小最大都为N/2,所以最多分治NlogN层,每层都是N 所以是O(NlogN)。 【具体流程】 1,选取一个点,将无根树变成有根树 为了使每次的处理最优,我们通常要选取树的重心。 何为“重心”,就是要保证与此点连接的子树的节点数最大值最小,可以防止被卡。 重心求法: 1。dfs一次,算出以每个点为根的子树大小。 2。记录以每个节点为根的最大子树大小 3。判断:如果以当前节点为根更优,就更新当前根。 void getroot(int v,int fa) { son[v] = 1; f[v] = 0;//f记录以v为根的最大子树的大小 for(int i = head[v];i;i=e[i].next) if(e[i].to != fa && !vis[e[i].to]) { getroot(e[i].to,v);//递归更新 son[v] += son[e[i].to]; f[v] = max(f[v],son[e[i].to]);//比较每个子树 } f[v] = max(f[v],sum-son[v]);//别忘了以v父节点为根的子树 if(f[v] < f[root]) root = v;//更新当前根 } 2、处理连通块中通过根节点的路径。 (注意