- zyssssss 的博客
树上问题【待填】
- 2024-1-19 21:23:31 @
树上问题
前言
树是一种伟大的植物
啊不对
树是一种伟大的发明
如果需要了解关于树的基础知识
请启动OI Wiki
树的重心
定义
找到一个点,其所有的子树(包括向上的)中最大的节点数最少,那么这个点就是这棵树的重心。
删去重心后,可以使生成的多棵树尽可能平衡。
性质
- 树的重心如果不唯一,则至多有两个,且这两个重心相邻。
- 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。
- 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。
- 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。
- 在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
求法
按定义求
在 DFS 中计算每个子树的大小,记录向下的子树的最大大小,利用总点数 - 当前子树的大小得到向上的子树的大小,然后就可以依据定义找到重心了。
void dfs(int u, int fa)
{
size[u] = 1;
dp[u] = 0;
for(int i=head[u];i;i=edge[i].next)
{
int v = edge[i].to;
if(v==fa)
continue;
dfs(v, u);
size[u] += size[v];
dp[u] = max(dp[u], size[v]);
}
dp[u] = max(dp[u], N-size[u]); //上面提到的处理
if(dp[u]<dp[ans])
ans = u;
}
附例题
点分治
点分治用于处理与树的路径有关的问题
它的核心是:处理过重心的路径,在子树中的路径递归处理
虚树
动态树LCT
引用来源 侵删