[ABC036D] 塗り絵 題解

PerchLootie發表於2024-06-07

題意

題面講挺清楚的就不簡化了。

思路

樹上求方案數,很明顯是樹上 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;
}

相關文章