Solution
考虑树形dp, 表示以 为根的子树至少含有一个黑节点的方案数(全白的后面+1即可)
那么考虑两种情况
- 染为黑色, 则子节点为什么颜色都无所谓, ( 为子节点), 其中1表示子结点的子树全为1
- 染为白色, 则子节点必须只有一个黑, ( 为子节点)
那么最后答案就是 加上空集的方案 即一个黑都没有
Code
/* autor: Kurisu 2020年4月26日19:14:26 */ #include<bits/stdc++.h> using namespace std; const long long inf = 1e18; const int N = 1e6 + 5; const double eps = 1e-10; const int mod = 1e9 + 7; typedef long long ll; struct Edge{ int v, nextz; }edge[N << 1]; int head[N], tot; ll qpow(ll a, ll b) { ll res = 1; while(b) { if(b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; } void addedge(int u, int v) { edge[tot].v = v; edge[tot].nextz = head[u]; head[u] = tot++; } ll dp[N]; void dfs(int u, int fa) { dp[u] = 1; ll res = 0; for(int i = head[u]; ~i; i = edge[i].nextz) { int v = edge[i].v; if(v == fa) continue; dfs(v, u); dp[u] *= (1 + dp[v]); // 当前为黑 dp[u] %= mod; res = (res + dp[v]) % mod; // 当前为白 } dp[u] += res; } int main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n; memset(head, -1, sizeof(head)); cin >> n; for(int i = 1; i <= n - 1; i++) { int u, v; cin >> u >> v; addedge(u, v); addedge(v, u); } dfs(1, -1); cout << (dp[1] + 1) % mod << "\n"; return 0; }