D-月之暗面(树形dp)

目录

题目描述

输入描述:

输出描述:

输入

输出

输入

输出

输入

输出

思路:

代码:


题目描述

I'll see you on the dark side of the moon.

我们将在月之暗面相会。

给出一棵 n个点的树,有 x 种普通颜色,y 种特殊颜色

现在要给树上的每个节点染色,普通颜色染色没有限制,但两个相邻的节点不能染相同颜色的特殊颜色

求染色方案数,答案对 998244353 取模。

输入描述:

第一行三个整数 n,x,y ( 1≤n≤106,1≤x,y≤109 ) ,分别表示树的节点数,普通颜色的种数,特殊颜色的种数

接下来n−1 行描述这棵树,每行两个整数 u,v( 1≤u,v,≤n ) 表示从 u 到 v 有一条树边

保证输入的树合法。

输出描述:

一行一个整数,表示答案。

示例1

输入

2 1 2
1 2

输出

7

示例2

输入

5 3 3
1 2
1 3
3 4
3 5

输出

5664

示例3

输入

11 45 14
6 5
6 7
7 9
7 8
9 2
8 10
2 1
8 3
10 4
4 11

输出

188688550

思路:

1,用链式前向星建树,用转移方程做题

2,dp[i][j]第i节点,j表示的是普通颜色还是特殊颜色,

3,dp[i][0]=dp[i][0]*(dp[i-1][0]*x%mod+dp[i-1][1]*y%mod)%mod;该位为普通颜色

dp[i][1]=dp[i][1]*(dp[i-1][0]*x%mod+dp[i-1][1]*(y-1)%mod)%mod;该位为特殊颜色

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int maxj = 1e6+100 , mod = 998244353;
int v[maxj],dp[maxj][2],tot,nex[maxj],head[maxj],vis[maxj];
int n,x,y;
void add ( int u, int v1 ){
    ++tot;
    v[tot]=v1;
    nex[tot] = head[u];
    head[u]=tot;//链式前向星
}
void dfs(int u,int fa){
    dp[u][0] = dp[u][1] = 1;
    for(int i = head[u] ; i ; i = nex[i] ) {
        int v1 = v[i] ;
        if(v1 == fa) continue ;
        dfs(v1,u);
        dp[u][0]=dp[u][0]*(dp[v1][0]*x%mod+dp[v1][1]*y%mod)%mod;
        dp[u][1]=dp[u][1]*(dp[v1][0]*x%mod+dp[v1][1]*(y-1)%mod)%mod;
    }
}
int32_t main(){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n>>x>>y;
    int be=1;
    int flag=1;
    for(int i=1;i<=n-1;++i){
        int u,v;
        cin>>u>>v;
//         if(flag){
//             be=u;
//             flag=0;
//         }
        add(u,v);//有向图,从没到达过的地方开始
//       add(v,u);//无向图,从没开始的地方开始,开始不同
        vis[v]++;
    }
    for(int i=1;i<=n-1;++i){
        if(vis[i]==0){be=i;break;}
    }
    dfs(be,-1);
    cout<<(dp[be][0]*x%mod+dp[be][1]*y%mod)%mod<<'\n';
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值