855C - Helga Hufflepuff's Cup

题意

要求构建一棵树,树上至多可以存在 \(x\) 个权值为 \(k\) 的重要点,且与重要点连边的点的权值必须小于 \(k\),问有多少种构树方案。

分析

树形DP。

有 \(dp[u][s][cnt]\),表示以 \(u\) 为根结点的子树,重要点的数目为 \(cnt\) 时的方案数,其中 \(s=0\) 表示 \(u\) 的权值小于 \(k\) ,\(s=1\) 表示 \(u\) 的权值等于 \(k\) ,\(s=2\) 表示 \(u\) 的权值大于 \(k\)。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 1e5 + 10;
vector<int> G[MAXN];
int n, m, k, x;
int dp[MAXN][3][11];
void dfs(int fa, int u) {
dp[u][0][0] = k - 1; dp[u][1][1] = 1; dp[u][2][0] = m - k;
for(auto v : G[u]) {
if(v != fa) {
dfs(u, v);
int tmp[3][11] = {0};
for(int i = 0; i <= x; i++) {
for(int j = i; j <= x; j++) {
tmp[0][j] = (tmp[0][j] + (ll)dp[u][0][j - i] * ((dp[v][0][i] + dp[v][1][i]) % MOD + dp[v][2][i]) % MOD) % MOD;
tmp[1][j] = (tmp[1][j] + (ll)dp[u][1][j - i] * dp[v][0][i] % MOD) % MOD;
tmp[2][j] = (tmp[2][j] + (ll)dp[u][2][j - i] * (dp[v][0][i] + dp[v][2][i]) % MOD) % MOD;
}
}
memcpy(dp[u], tmp, sizeof tmp);
}
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m;
for(int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
cin >> k >> x;
dfs(1, 1);
int ans = 0;
for(int i = 0; i < 3; i++) {
for(int j = 0; j <= x; j++) {
ans = (ans + dp[1][i][j]) % MOD;
}
}
cout << ans << endl;
return 0;
}
05-27 18:09