NEUOj 涂色

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值