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 }