Educational DP Contest P - Independent Set(树形dp)

P - Independent Set

原题链接:https://atcoder.jp/contests/dp/tasks/dp_p

题目大意:

给一棵树,用黑白两色给节点染色,其中两个相邻节点不能同为黑色,求染色的所有方法。

解题思路:

树形$dp$,建一个二维数组$dp$,$dp[i][j]$为第$i$个点为$j$($j=0,1$即黑白)所有情况,然后找递推式,以1为根节点dfs即可。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define debug(a) cout<<#a<<":"<<a<<endl;
 5 const ll INF=0x3f3f3f3f;
 6 const ll N=1e6+7;
 7 const ll mod=1e9+7;
 8 ll maxn,minn;
 9 ll T,n,m;
10 vector<ll>mp[N];
11 ll dp[N][2];
12 
13 void dfs(ll a,ll p){
14     ll len=mp[a].size();
15     if(len==1&&a!=1){
16         dp[a][0]=1;
17         dp[a][1]=1;
18         return ;
19     }
20     for(ll i=0;i<len;i++){
21         if(mp[a][i]!=p){
22             dfs(mp[a][i],a);
23             ll ans1=(dp[mp[a][i]][0]+dp[mp[a][i]][1])%mod;
24             ll ans2=dp[mp[a][i]][0];
25             dp[a][0]=(dp[a][0]*ans1)%mod;
26             dp[a][1]=(dp[a][1]*ans2)%mod;
27         }
28     }
29     
30 }
31 
32 int main(){
33     ll u,v;
34     cin>>n;
35     for(ll i=1;i<n;i++){
36         dp[i][0]=dp[i][1]=1;
37         scanf("%lld%lld",&u,&v);
38         mp[u].push_back(v);
39         mp[v].push_back(u);
40     }
41     dp[n][0]=dp[n][1]=1;
42     dfs(1,0);
43     cout<<((dp[1][0]+dp[1][1])%mod)<<endl;
44     return 0;
45 }

 

 

 
posted @ 2020-05-08 20:30  yya雨  阅读(240)  评论(0编辑  收藏  举报