RT,设 fi,j 为第 i 层用了 j 个节点的最大节点数量,先预处理第 i 层总共的节点数量 layeri,然后暴力转移:
fi,j=j+k=0maxmin(j,layeri−1)fi−1,k
求证明/证伪:这样正确。
个人感觉是选择所有节点的父节点一定最优,这样不劣,所以是正确的?
然后经过一点优化就到了时空 O(n),然而并没有用到单调栈优化,很奇怪,不知道为啥,还是数据过水?
顺带代码:
const int N = 5e5 + 10;
int n ,dep[N] ,layer[N] ,f[2][N] ,pre[2][N] ,ans;
vector <int> edge[N];
inline void dfs (int u ,int fath){
dep[u] = dep[fath] + 1;
layer[dep[u]] ++;
for (int v : edge[u]) {
if (v == fath) continue;
dfs (v ,u);
}
} signed main() {
n = read ();
up (i ,1 ,n - 1) {
int u = read () ,v = read ();
edge[u].push_back (v) ; edge[v].push_back (u);
}
dfs (1 ,0);
//f[i][j]:在层 i 用了 j 个节点的最大数量。
f[1][1] = 1;
up (j ,1 ,layer[1]) pre[1][j] = 1;
up (i ,2 ,n) {
up (j ,1 ,layer[i]) pre[i & 1][j] = f[i & 1][j] = 0;
up (j ,1 ,layer[i]) {
int mx = pre[(i & 1) ^ 1][min (layer[i - 1] ,j)];
f[i & 1][j] = j + mx;
pre[i & 1][j] = max (pre[i & 1][j - 1] ,f[i & 1][j]);
ans = max (ans ,f[i & 1][j]);
}
} writeln (ans);
return 0;
}