題意
題面講挺清楚的就不簡化了。
思路
樹上求方案數,很明顯是樹上 dp
。
設 $dp_{i,0/1}$ 表示第 $i$ 個點塗成白/黑色的方案數。
當前結點如果為白色,那麼它的子節點塗成什麼顏色都沒關係,根據分步乘法原理,將它子結點塗成白/黑色的方案數之和乘起來即可;當前結點如果為黑色,那麼它的子節點只能塗成白色,根據分步乘法原理,將它子結點塗成白色的方案數乘起來即可。如果 $i$ 是葉子結點,那麼 $dp_{i,0}=dp_{i,1}=1$。
形式化的講:
- $dp_{i,0}=\prod dp_{j,0}+dp_{j,1}$
- $dp_{i,1}=\prod dp_{j,0}$
其中 $j$ 表示 $i$ 的一個子結點。
記得取模。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int n,m;
int head[200005],cnt=1;
int dp[100005][2];
int ans;
struct node{
int to,next;
}edge[200005];
void add(int x,int y){
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
}
void dfs(int x,int fa){
int num=0;
dp[x][0]=1;
dp[x][1]=1;
for(int i=head[x];i;i=edge[i].next){
int u=edge[i].to;
if(u==fa) continue;
num++;
dfs(u,x);
dp[x][0]*=(dp[u][0]+dp[u][1])%mod;
dp[x][0]%=mod;
dp[x][1]*=dp[u][0];
dp[x][1]%=mod;
}
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
printf("%lld",(dp[1][0]+dp[1][1])%mod);
return 0;
}