树形DP
加分二叉树 洛谷P1040
注意中序遍历的特点:当根节点编号k时,编号小于k的都在其左子树上,编号大于k的都在右子树
转移方程 f[i,j]=max{f[i,k-1]*f[k+1,j]+d[k]} ,f[i,j]表示中序遍历i到j的二叉树最大加分 时间复杂度O(N3)
#include
#include
#include<string>
#include
#include
#include<set>
#include
P2015 二叉苹果树
#include
#include
#include<string>
#include
#include
#include<set>
#include
洛谷P1352 没有上司的舞会
#include
#include
#include<string>
#include
#include
#include<set>
#include
树上的常见操作
const int maxn = 100005;
vector<int> v[maxn];
int _size[maxn]; //结点大小
int mx_size[maxn];
int depth[maxn];
int Max[maxn];
int val[maxn];
void getsize(int x) { //一棵N个点的无权树,问每个结点的大小
_size[x] = 1;
for (int i = 0; i < v[x].size(); i++) {
getsize(v[x][i]);
_size[x] += _size[v[x][i]];
}
}
void getdep(int x) { //一棵N个点的无权树,问每个结点的深度
for (int i = 0; i < v[x].size(); i++) {
depth[v[x][i]] = depth[x] + 1;
getdep(v[x][i]); //自顶向下
}
}
void getmax(int x) { //一棵N个点的点权树,问每个子树的点权和,点权最大值
Max[x] = val[x];
for (int i = 0; i < v[x].size(); i++) {
getmax(v[x][i]);
Max[x] = max(Max[x], Max[v[x][i]]);
}
}
求树的重心
定义:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡
C++代码
#include
#include
#include<string>
#include
#include
#include<set>
#include