Independent Set

Independent Set

给一棵树,每一个点可以染成黑色或白色,任意两个相邻节点不能都是黑色,求方案数,结果对 \(10^9+7\) 取模。

样例输入

3
1 2
2 3

样例输出

5

树形DP:

我们设状态 \(dp_{i,0/1}\) 为以 \(i\) 为根节点,且根节点颜色为( \(1 - 黑色\)\(0 - 白色\) )的子树中染色的方案数,那么可得状态转移方程为:

\(i\) 节点为白色时:

$ dp_{i,0} = \prod (dp_{to_i,0} + dp_{to_i,1}) $

为黑色时:

\(dp_{i,1} = \prod dp_{to_i,0}\)

状态初始化:

显然,当 \(i\) 节点为根节点时,$ dp_{i,0} = dp_{i,1} = 1$

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 7;
const int MOD = 1e9 + 7;
vector<int> tree[MAXN];
long long dp[MAXN][2];
int n;
int x,y;
void dfs(int pos,int fa){
	int cnt = 0;
	for(int to : tree[pos]){
		if(to != fa){
			cnt++;
			dfs(to,pos);
			dp[pos][1] = (dp[pos][1] * dp[to][0]) % MOD;
			dp[pos][0] = (dp[pos][0] * (dp[to][1] + dp[to][0]) % MOD) % MOD;
		}
	}
	if(cnt == 0){
		dp[pos][0] = dp[pos][1] = 1;
	}
}
int main(){
	scanf("%d", &n);
	for(int i = 1;i <= n;i++){
		dp[i][0] = dp[i][1] = 1;
	}
	for(int i = 1;i <= n - 1;i++){
		scanf("%d%d", &x, &y);
		tree[x].push_back(y);
		tree[y].push_back(x);
	}
	dfs(1,0);
	cout<<(dp[1][0] + dp[1][1]) % MOD;
	return 0;
}

\(done\)

posted @ 2024-09-10 19:06  wyl123ly  阅读(3)  评论(0编辑  收藏  举报