题意
题面讲挺清楚的就不简化了。
思路
树上求方案数,很明显是树上 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;
}
标签:结点,int,题解,edge,涂成,ABC036D,dp,mod
From: https://www.cnblogs.com/PerchLootie/p/18237779