[题解]AT_abc287_f [ABC287F] Components
思路
定义 表示在以 为根的子树中(包括 )选出 个连通块,且 不选/选 的方案数。
假设我们在 DFS 过程中,当前枚举到以 为根节点的情况,那么显然有 。
然后,我们从 开始向其儿子节点搜索,假设当前枚举到的点是 。
那么,我们对于每一个 ,我们都可以对 的选取情况作分类讨论(其中 表示以 为根的子树在没有 之前的连通块数量,和以 为根的子树中连通块的数量):
- 如果不选,那么两棵子树合并,连通块数量为 ,那么有 。
- 如果选,那么还需要根据 的选取情况进行分类讨论:
- 如果 不选,那么两棵子树合并,连通块数量还是为 ,那么有 。
- 如果 选,那么两棵子树合并,由于 都要选,那么,包含 的两个连通块将合并为一个,所以连通块数量为 ,那么有 。
Code
#include <bits/stdc++.h>
#define int long long
#define re register
using namespace std;
const int N = 5010,M = 1e4 + 10,mod = 998244353;
int n;
int idx,h[N],e[M],ne[M];
int dp[N][N][2];
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 1) + (r << 3) + (c ^ 48);
c = getchar();
}
return r * w;
}
inline void add(int a,int b){
ne[idx] = h[a];
e[idx] = b;
h[a] = idx++;
}
inline int dfs(int u,int fa){
int sz = 1;
dp[u][0][0] = dp[u][1][1] = 1;
for (re int i = h[u];~i;i = ne[i]){
int j = e[i];
if (j == fa) continue;
int ssz = dfs(j,u);
for (re int a = sz;~a;a--){
for (re int b = ssz;b;b--) dp[u][a + b][0] = (dp[u][a + b][0] + dp[u][a][0] * (dp[j][b][0] + dp[j][b][1]) % mod) % mod;
// b 不能枚举到 0,因为如果 b 枚举到 0,那么将会有 dp[u][a][0] = 2 * dp[u][a][0] % mod,然而这种状态肯定是我们计算过的,所以不能枚举到 0
}
for (re int a = sz;a;a--){
for (re int b = ssz;b;b--){
dp[u][a + b][1] = (dp[u][a + b][1] + dp[u][a][1] * dp[j][b][0] % mod) % mod;
dp[u][a + b - 1][1] = (dp[u][a + b - 1][1] + dp[u][a][1] * dp[j][b][1] % mod) % mod;
}
}
sz += ssz;
}
return sz;
}
signed main(){
memset(h,-1,sizeof(h));
n = read();
for (re int i = 1;i < n;i++){
int a,b;
a = read();
b = read();
add(a,b);
add(b,a);
}
dfs(1,-1);
for (re int i = 1;i <= n;i++) printf("%lld\n",(dp[1][i][0] + dp[1][i][1]) % mod);
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18262937
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统