A tree has a k black node, the remaining nodes are white, dividing it into K-tree, so that each tree has only 1 black nodes, a total of how many kinds of partition scheme.
Personal feeling this problem is more difficult. It is assumed that DP (I,0..1) represents 0 of the sub-species with the root node of I. Number of partition schemes for 1 black nodes.
When node I is white, the node for each child of it is processed:
When DP (i, 0) is obtained:
1, the node is connected with the child node, but to ensure that the child node is located in the child tree does not have a black node;
2, the node is not connected with the child node, the child node to ensure that the child tree has a black node;
i.e. DP (i, 0) =π (DP (j,0) + DP (j, 1)), where j is the child node of I
When seeking DP (i,1):
Connect the node with one of each child nodes, and ensure that the child node is located in a subtree of 1 black nodes (so there are k cases, K is the number of children of that node), and for the rest of the node can choose to connect can also choose not to connect, if connected, ensure that the child node is not in the subtree of black, if not is guaranteed to be black, so for each remaining
The child node's processing scheme book has DP (j,0) + DP (j,1), then multiplies each child's solution book, and finally adds all the schemes together.
When the node I is black, the DP (I, 0) must be 0;
For DP (I, 1) for each child node of I also have two options, or not even, if connected, it is guaranteed that the child node is not in the subtree of black, if not connected, it is guaranteed to have black, that is, for each child node processing number common
DP (j, 0) + DP (j, 1), then multiply the number of scenarios each child processes.
The final DP (0,1) is the answer, assuming that the 0 node is the root node.
The process can be added a small optimization, when a child node is located in the whole subtrees tree without a black node, then the node is bound to its parent node, so the calculation can not consider the node.
#include <stdlib.h> #include <stdio.h> #include <algorithm> #include <vector>using namespace Std;//int Values[500001];//long long sums[500001]; #define Modvalue 1000000007#define mod (x) if ((x) > Modvalue) x%= mod Value;struct edge{int to;int i;int totalcolor; Edge () {totalcolor = 0;}}; int compp (const void* A1, const void* A2) {return * ((int*) A2)-* ((int*) A1);} Vector<edge> g[100001];int color[100001];long long res[100001][2];//int tmp[100001];bool Visited[100001];void Addedge (int from, int. to) {Edge edge;edge.to = TO;EDGE.I = G[to].size (); G[from].push_back (edge); edge.to = FROM;EDGE.I = G[from].size ()-1; G[to].push_back (edge);} int Countcolor (int node) {Visited[node] = True;int count = 0;if (Color[node]) {count = 1;} for (int i = 0; i < g[node].size (); i++) {edge& Edge = g[node][i];if (! Visited[edge.to]) {Edge.totalcolor = Countcolor (edge.to); count + = Edge.totalcolor;}} return count;} void Getans (int node) {Visited[node] = true;long long ans = 1;int Countofcolor = 0;vector<int> tmp;for (int i = 0; i < g[node].size (); i++) {edge& Edge = G[node][i];if (visited[edge.to]) {con Tinue;} tmp[countofcolor++] = i; Getans (edge.to); if (Edge.totalcolor) {tmp.push_back (i); countofcolor++;//tmp[countofcolor++] = i;}} Res[node][0] = 0;res[node][1] = 0;long long tmp1 = 1;long long tmp0 = 1;if (! Color[node]) {tmp1 = 0;} for (int i = 0; i < Countofcolor; i++) {if (Color[node]) {edge& Edge = G[node][tmp[i]];tmp1 *= (res[edge.to][1] + res [Edge.to] [0]); MOD (TMP1); tmp0 = 0;} else{edge& edge1 = G[node][tmp[i]];tmp0 *= (res[edge1.to][1] + res[edge1.to][0]); MOD (tmp0); long Long Tmp3 = 1;for (int j = 0; J < Countofcolor; J + +) {edge& Edge = g[node][tmp[j]];if (i = = j) {Tmp3 * = Res[edge.to][1]; MOD (Tmp3);} Else{tmp3 *= (res[edge.to][1] + res[edge.to][0]); MOD (Tmp3);}} TMP1 + = Tmp3;} if (i = = countofcolor-1) {res[node][0] + = tmp0;res[node][1] + tmp1; MOD (Res[node][0]); MOD (res[node][1]);}} if (Countofcolor = = 0) {Res[node][0] = Color[node]? 0:1;res[node][1] = COlor[node]? 1:0;}} int main () {#ifdef _debugfreopen ("E:\\in.txt", "R", stdin), #endif//_debugint n;scanf ("%d", &n), for (int i = 0; i < n-1; i++) {int value;scanf ("%d", &value); Addedge (i + 1, value);} for (int i = 0; i < n; i++) {int value;scanf ("%d", &value); Color[i] = value;} memset (visited, 0, sizeof (visited)); Countcolor (0); memset (visited, 0, sizeof (visited)); Getans (0);p rintf ("%i64d\n", res[0][1]); return 0;}
Codeforces 461b-appleman and Tree DP