CF461B Appleman and Tree (樹DP)

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   os   io   strong   for   

CF462D

Codeforces Round #263 (Div. 2) D

Codeforces Round #263 (Div. 1) B

B. Appleman and Treetime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard output

Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.

Consider a set consisting of k (0 ≤ k < n) edges of Appleman‘s tree. If Appleman deletes these edges from the tree, then it will split into (k + 1) parts. Note, that each part will be a tree with colored vertices.

Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).

Input

The first line contains an integer n (2  ≤ n ≤ 105) — the number of tree vertices.

The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.

The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.

Output

Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).

Sample test(s)Input
3
0 0
0 1 1
Output
2
Input
6
0 1 1 0 4
1 1 0 0 1 0
Output
1
Input
10
0 1 2 1 4 4 4 0 8
0 0 0 1 0 1 1 0 0 1
Output
27

題意:有n個結點的樹,結點編號0~n-1,0為根,分別給出1~n-1的父親,再給出0~n-1各個結點的顏色(0為白,1為黑),要將其中一些邊切掉,使每個聯通塊有且只有1個黑點,求切法種類數。

題解:樹形DP。

從根DFS,f[x][0]表示對{x點和它的子樹、x點串連父親結點的邊}這一整坨,有多少種方案使得x這個聯通塊沒黑點(x是黑點的時候這個也不為0,是把x的父邊切掉的種類數)

f[x][1]是這個聯通塊有黑點的種類數。

 

太難了!怪不得大家都掉分飛起,雖然題解的代碼看起來很短,我根本想不出來啊看了半天還是不懂啊!

具體還是看代碼吧,寫了點注釋,這個統計方法太碉了,我也弄得不是很清楚,算了日後再說。

代碼:

 1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set>10 #include<stack>11 #include<queue>12 using namespace std;13 #define ll long long14 #define usll unsigned ll15 #define mz(array) memset(array, 0, sizeof(array))16 #define minf(array) memset(array, 0x3f, sizeof(array))17 #define REP(i,n) for(i=0;i<(n);i++)18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)19 #define RD(x) scanf("%d",&x)20 #define RD2(x,y) scanf("%d%d",&x,&y)21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)22 #define WN(x) printf("%d\n",x);23 #define RE  freopen("D.in","r",stdin)24 #define WE  freopen("1biao.out","w",stdout)25 #define mp make_pair26 #define pb push_back27 28 const int maxn=111111;29 const int MOD=1e9+7;30 31 int n;32 int a[maxn];33 34 struct Edge {35     int next,v;36 } e[2*maxn];37 int en=0;38 int head[maxn];39 40 void add(int x,int y) {41     e[en].v=y;42     e[en].next=head[x];43     head[x]=en++;44 }45 46 bool u[maxn];47 ll f[maxn][2];///f[x][j] j=1表示x所在聯通塊有黑點,0表示無黑店 的種類數,包括x串連父親的邊和子樹所有的邊48 void dfs(int x){49     //printf("[in %d]",x);50     int i;51     u[x]=1;52     f[x][0]=1;53     f[x][1]=0;///先假設當前點是個白點54     for(i=head[x]; i!=-1; i=e[i].next) {55         if(!u[e[i].v]) {56             dfs(e[i].v);57             f[x][1]=(f[x][1]*f[e[i].v][0] + f[x][0]*f[e[i].v][1])%MOD;///有黑點的情況,先用已經統計的有黑點的情況乘一發兒子沒黑點的情況,然後用已經統計的沒黑點的情況乘一發兒子有黑點的情況58             f[x][0]=f[x][0]*f[e[i].v][0]%MOD;///沒黑點的情況直接乘兒子沒黑點的情況59         }60     }61     u[x]=0;62     ///下面是對x點的父邊的處理63     if(a[x]==0)f[x][0]=(f[x][0]+f[x][1])%MOD;///x是白點,兒子要是有黑點,砍了x的父邊就是沒黑點,所以沒黑點(f[x][0])的情況要加上有黑點的情況(f[x][1])64     else f[x][1]=f[x][0];///x點是黑點,那不砍父邊的情況(f[x][1])只有讓x的兒子都不黑,砍父邊的情況(f[x][0])也是x的兒子都不黑,因為x自己黑嘛,兒子再黑就連到一起了65     //printf("[out %d,flag=%d,re=%I64d,a[x]=%d]\n",x,flag,re,a[x]);66 }67 68 69 ll farm() {70     if(n==1)return 1;71     mz(u);72     dfs(0);73     return f[0][1];74 }75 76 int main() {77     int i;78     int x;79     RD(n);80     memset(head,-1,sizeof(head));81     en=0;82     REP(i,n-1) {83         scanf("%d",&x);84         add(i+1,x);85         add(x,i+1);86     }87     for(i=0; i<n; i++)88         scanf("%d",&a[i]);89     printf("%I64d",farm());90     return 0;91 }
View Code

 

CF461B Appleman and Tree (樹DP)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.