G将军的敢死队——树状DP

当前节点的两种情况:

1.beChoosed = {son.beAbandoned乘积}  //当前节点选中的情况下,子节点都不能选

2.beAbandoned = {(son.beAbandoned + son.beChoosed)乘积} //当前节点不选的情况下,子节点所有情况都算上

ps:最终要减去一种所有节点都未被选中的情况  -1

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <list>
 4 #define MOD 10007
 5 #define MAXN 100002
 6 using namespace std;
 7 int n;
 8 struct node{
 9     int parent;
10     list<int>son;
11     int son_count;
12     int beChoosedCount,beAbandonedCount;
13 }num[MAXN];
14 
15 void dfs(int id)
16 {
17     for(int i=0;i<num[id].son_count;++i)
18     {
19         int tmp = num[id].son.front();
20         dfs(tmp);
21         num[id].son.pop_front();
22         num[id].beChoosedCount *= num[tmp].beAbandonedCount%MOD;
23         num[id].beAbandonedCount *= (num[tmp].beChoosedCount+num[tmp].beAbandonedCount)%MOD;    
24     }
25 
26 }
27 int main()
28 {
29     cin>>n;
30     num[1].beChoosedCount=1;
31     num[1].beAbandonedCount=1;
32     for (int i = 2; i <= n; ++i)
33     {
34         
35         cin>>num[i].parent;
36         num[num[i].parent].son.push_back(i);
37         num[num[i].parent].son_count++;
38         num[i].beAbandonedCount=1;
39         num[i].beChoosedCount=1;
40     }
41 
42     dfs(1);
43     cout<<(num[1].beAbandonedCount+num[1].beChoosedCount-1)%MOD;
44     return 0;
45 }
原文地址:https://www.cnblogs.com/sylvialucy/p/5032875.html