题解 P4516 【[JSOI2018]潜入行动】
简单的树形dp。
设
复杂度
然后观察数据,
这时再写链表显然是不明智的做法,利用vector内存连续的特性,一般情况下比链表要快了。就不会出现提交记录里面的一片
现在各大比赛纷纷支持C++11,还开O2,以后存图是不是都不用写链表了(雾
虽然这里面没有这篇题解但我还是要放出来!
void dfs(int u, int fa) {
siz[u] = 1;
f[u][0][0][0] = f[u][1][1][0] = 1;
for (auto v : E[u])
if (v != fa) {
dfs(v, u);
for (int i = 0, lim = min(siz[u], k); i <= lim; i++) {
g[i][0][0] = f[u][i][0][0], f[u][i][0][0] = 0;
g[i][0][1] = f[u][i][0][1], f[u][i][0][1] = 0;
g[i][1][0] = f[u][i][1][0], f[u][i][1][0] = 0;
g[i][1][1] = f[u][i][1][1], f[u][i][1][1] = 0;
}
//这样大概,可能,也许比两个循环要快那么一点点吧。
for (int i = 0, lim = min(siz[u], k); i <= lim; i++)
for (int j = 0, lim2 = min(siz[v], k); j <= lim2 && i + j <= k; j++) {
add(f[u][i + j][0][0], g[i][0][0] * f[v][j][0][1]);
add(f[u][i + j][0][1], g[i][0][1] * (f[v][j][0][1] + f[v][j][1][1]) + g[i][0][0] * f[v][j][1][1]);
add(f[u][i + j][1][0], g[i][1][0] * (f[v][j][0][0] + f[v][j][0][1]));
add(f[u][i + j][1][1], g[i][1][0] * (f[v][j][1][0] + f[v][j][1][1]) + g[i][1][1] * ((ll)f[v][j][0][0] + f[v][j][0][1] + f[v][j][1][0] + f[v][j][1][1]));
}
siz[u] += siz[v];
}
}