记fi,j,k为距离i点最近的祖先或i点本身的点为j,在i点与i的子树中共设立k个伐木场的最小代价。
转移如下:
for (int i = 0; i <= n; ++i) {
if (dis[i][x] != -1 && dis[i][x]) f[x][i][0] = a[x] * dis[i][x];
f[x][x][1] = 0;
if (!x) f[x][x][0] = 0;
}
for (int i = head[x]; ~i; i = e[i].next) {
int y = e[i].v;
dp(y);
for (int j = 0; j <= n; ++j) {
if (dis[j][x] == -1) continue;
for (int l = k; l >= 0; --l) {
if (f[x][j][l] < inf && f[y][j][0] < inf) f[x][j][l] = f[x][j][l] + f[y][j][0];
if (f[x][j][l] < inf && f[y][y][0] < inf) f[x][j][l] = f[x][j][l] + f[y][y][0];
for (int m = 1; m <= l; ++m) {
if (f[x][j][l - m] < inf && min(f[y][j][m], f[y][y][m]) < inf)
f[x][j][l] = min(f[x][j][l],
f[x][j][l - m] +
min(f[y][j][m],
f[y][y][m]));
}
}
}
}