NEUOj 涂色

这篇博客介绍了如何使用树上动态规划(DP)解决一个关于树节点涂色的问题。给定一棵有N个节点的树,每个节点可以选择涂成黑色或白色,但相邻节点不能同色。题目要求找出所有可能的涂色方案数并模1e9+7。通过递归的DFS遍历树的结构,博主给出了计算每个节点黑白方案数的方法,并提供了C++代码实现。最终,博主展示了如何从根节点开始计算得到总方案数。
摘要由CSDN通过智能技术生成

NEUOj 涂色

没找到ATC里面对应哪个题。

就把题直接粘贴过来了

Problem Statement

有一棵有N个节点的树,节点编号为1,2,,N,对每个i (1iN1),第i条边连着x**iy**i节点。

Taro 决定将每个节点都涂成黑色或者白色,不能将两个相邻的节点同时涂黑。

找到他能涂色的方案数并对1e9+7取模。

Constraints

  • 所有输入均为整数
  • 1N1e5
  • 1x**i,y**iN
  • 所给图是一棵树

Input

N
x1 y1
.
.
xN yN

Output

输出他能涂色的方案数并对1e9+7取模。

输入样例

4
1 2
1 3
1 4
                            

输出样例

9
                            

提示:

有9种方法涂色:

img

用树上dp,white[i] 表示i位置取白色时的方案数,black[i]表示i位置取黑色时的方案数。

那么叶子节点均取1。对于一个中间节点i,对于white[i]来说是每个子树的black[k]+white[k] 相乘, 对于black[i]是white[k]相乘。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
 
using namespace std;
const int N = 1e5 + 100;
const int mod = 1e9 + 7;
typedef long long ll;
 
vector<int> G[N];
ll black[N], white[N];
 
void dfs(int cur, int fa) {
    if (G[cur].size() == 1 && fa != -1) {
        black[cur] = 1;
        white[cur] = 1;
        return;
    }
    ll tem1 = 1, tem2 = 1;
    for (int i = 0; i < G[cur].size(); i++) {
        int nx = G[cur][i];
        if (fa == nx) continue;
        dfs(nx, cur);
        tem1 *= (black[nx] + white[nx]);
        tem2 *= white[nx];
        tem1 %= mod;
        tem2 %= mod;
    }
    black[cur] += tem2;
    black[cur] %= mod;
    white[cur] += tem1;
    white[cur] %= mod;
}
 
int main() {
    int n;
    cin >> n;
    for (int i = 1; i < n; i++) {
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    dfs(1, -1);
    cout << (black[1] + white[1]) % mod << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值