JZOJ 3034. 【NOIP2012模拟10.17】独立集

题目

Description

 


 

对于一棵树,独立集是指两两互不相邻的节点构成的集合。例如,图1有5个不同的独立集(1个双点集合、3个单点集合、1个空集),图2有14个不同的独立集,图3有5536个不同的独立集。


 


 

 

Input

 


 

输入文件名为 duliji.in。


第一行一个正整数n,表示点的数量。n最大为100000。


接下来n-1行,有两个整数a、b,表示编号为a、b的两个点之间有一条边,其中a、b大于等于1,小于等于n。


 

Output

 


 

      输出文件名为duliji.out。


输出一行,包含一个整数,表示独立集的数量。由于这个数很大,你只需要输出这个数除以10081的余数。


 

 

Sample Input

17
1 2
1 3
2 4
2 5
3 6
3 7
5 8
5 9
7 10
7 11
8 12
8 13
10 14
10 15
12 16
15 17

Sample Output

5536
 

Data Constraint

 

分析

 

  • 大概算个暴力??树形DP
  • f[i][0]为选择当前节点,f[i][1]为不选择当前节点
  • 如果当前节点选,那么就乘上他所有的子节点
  • 如果不选,那么就乘上他所有子节点选和不选的方案数和

 

代码

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 #define mod 10081 
 5 using namespace std;
 6 vector <int> e[100010];
 7 int flag[100010];
 8 int f[100010][2];
 9 void dfs(int x)
10 {
11     for(int i=0;i<e[x].size();i++)
12     {
13        if (!flag[e[x][i]])
14        {
15             flag[e[x][i]]=1;
16             dfs(e[x][i]);
17          f[x][1]=(long long)(f[x][1]*f[e[x][i]][0])%mod;
18          f[x][0]=(f[e[x][i]][0]+f[e[x][i]][1])%mod*f[x][0]%mod;
19        }
20     }
21 }
22 int main ()
23 {
24     int n;
25     cin>>n;
26     for (int i=1,x,y;i<=n-1;i++)
27     {
28         cin>>x>>y;
29         e[x].push_back(y);
30         e[y].push_back(x);
31     }
32     for (int i=1;i<=n;i++) sort(e[i].begin(),e[i].end());
33     for (int i=1;i<=n;i++) f[i][0]=f[i][1]=1;
34     flag[1]=1;
35     dfs(1);
36     cout<<(f[1][0]+f[1][1])%mod;
37 }

 

 

posted @ 2019-07-05 21:13  Melted_czj  阅读(182)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色