“今日头条杯”首届湖北省大学程序设计竞赛 D. Who killed Cock Robin(选择联通子图的方案数,树形dp)

题意:

给定n个点的树,求选出一个联通子图的方案数,答案对1e9+7取模。

数据范围:n<=2e5

解法:

设 d [ x ] 以 x 为 根 的 子 树 中 , 选 择 点 x 之 后 , 连 通 子 图 的 方 案 数 , 设 v 是 x 的 子 节 点 , 那 么 转 移 方 程 为 : 1. 如 果 选 择 点 v , 那 么 方 案 数 为 d [ x ] ∗ d [ v ] . 2. 如 果 不 选 择 点 v , 那 么 d [ x ] . 综 上 得 转 移 方 程 为 : d [ x ] = d [ x ] ∗ ( d [ v ] + 1 ) . 设d[x]以x为根的子树中,选择点x之后,连通子图的方案数,\\ 设v是x的子节点,那么转移方程为:\\ 1.如果选择点v,那么方案数为d[x]*d[v].\\ 2.如果不选择点v,那么d[x].\\ 综上得转移方程为:d[x]=d[x]*(d[v]+1). d[x]x,x,,vx,:1.v,d[x]d[v].2.v,d[x].:d[x]=d[x](d[v]+1).

code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
const int mod=1e7+7;
vector<int>g[maxm];
int d[maxm];
int n;
int ans;
void dfs(int x,int fa){
    d[x]=1;
    for(int v:g[x]){
        if(v==fa)continue;
        dfs(v,x);
        d[x]=d[x]*(d[v]+1)%mod;
    }
    ans=(ans+d[x])%mod;
}
signed main(){
    ios::sync_with_stdio(0);
    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<<ans<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值