WHU B Color 2017 Wuhan University Programming Contest 一道简单树形dp

本文介绍了一道经典的树形DP题目,通过构建一棵n个节点的树,并为每个节点提供M种颜色的选择,求解在相邻节点颜色不相同的条件下,有多少种不同的涂色方案。文章提供了详细的解题思路及C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

When Asuho was just a little girl, she has been loving stars, as there are so many romantic stories about old legends and the stars.
Today, as usual, Asuho went to the observatory with her beloved boyfriend, Kogasaka Ming, to see the splendid sky of galaxy. Sitting with Kogasaka shoulder to shoulder, Asuho thought nothing could make her happier.
“Asuho,” Kogasaka called Asuho softly. “I have a question about the Hoshizora(night sky with stars).”
“What’s it?” Asuho answered, happily. “I know everything about the stories, you can ask anything.”
Kogasaka smiled, “You see the stars? Just imagine there are nnn distinct stars in the sky while n−1n-1n−1 relationships connect them. Each relationship is between two stars and all stars are connected directly or indirectly. Now you need to divide thennn stars into mmm different types. Beware that no two directly connected stars should share the same type and some stars cannot be some types. I want you to tell me how many distinct solutions there could be.”
Suddenly the Stella meteor shower appeared, so the lovers forgot the question and started to admire the beautiful Hoshizora.
Asuho thought it was unbelievable that Kogasaka should ask her such a foolish question which she can’t solve. Of course she didn’t wish to reveal her poor math. So can you help her to tell the answer?
Input
The Input file contains several test cases.
For each case, the first line contains two integers nnn (2≤n≤1042\le n\le 10^42≤n≤10​4​​),mmm (1≤m≤201\le m\le 201≤m≤20)
The next n−1n-1n−1 lines, each line contains 2 integers xix_ix​i​​,yiy_iy​i​​ expressing relationships between the two stars.
The next nnn lines, each lines contains m numbers and each of the mmm is 0 or 1.
The iii-th number of the jjj-th line respect whether jjj-th star can be divided into the iii-th type. 1 means it could while 0 means not.
Output
For each test case, output one single line, containing the number of solutions module107+910^7+910​7​​+9
Examples
Input 1
4 6
1 2
1 3
1 4
1 1 1 1 1 0
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
Output 1
625
题意:给你一颗n个点的树,给你每个点的M种颜色,0代表不可涂,1代表可涂,问你有多少种涂色方案使相邻的颜色不同色
事实上这就是一道简单的树形dp,由于以前没经历过此类题,还在比赛中遇见了,于是geigei.
以下是状态转移方程:
dp[u][j] *= (dp1[v]-dp[v][j]);//意思是u结点选涂j色时,它的涂色方案数是其子结点涂色方案数的乘积(乘法原则)
dp1[u] = sum(dp[u][j]) j from 0 to M-1;//u结点的方案数是它选择所有可能颜色的方案数的总和(加法原则)

#include <iostream>
#include <vector>
#include <string.h>
#define LL long long
using namespace std;
vector <int> map[10002];
int cor[10001][22];
int N,M;
LL dp[10001][22],dp1[10001];
int rem[10001];
LL MOD = 10000009;
int dps(int s){
    if(rem[s])return 0;
    rem[s] = 1;
    int flag = 0;
    for(int i=0;i<map[s].size();i++){
        int to = map[s][i];
        if(dps(to)==0)continue;
        for(int j=0;j<M;j++){
            dp[s][j] *= (dp1[to]-dp[to][j]+MOD)%MOD;
            dp[s][j]%=MOD;
        }
    }
    for(int i=0;i<M;i++)dp1[s] += dp[s][i];
    dp1[s]%=MOD;
    return 1;
}
int main()
{
    while(cin>>N>>M){
        for(int i=1;i<=N;i++)map[i].clear();
        for(int i=0;i<N-1;i++){
            int a,b;
            cin>>a>>b;
            map[a].push_back(b);
            map[b].push_back(a);
        }
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                cin>>cor[i+1][j];
            }
        }
        for(int i=1;i<=N;i++){
            for(int j=0;j<M;j++){
                if(cor[i][j])dp[i][j] = 1;
                else dp[i][j] = 0;
            }
        }
        memset(dp1,0,sizeof(dp1));
        memset(rem,0,sizeof(rem));
        dps(1);
        cout<<dp1[1]<<endl;
    }   
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值