Source: Internet
Author: User

Label:

Nice tree-shaped DP. A node can walk many times, the biggest feature of the tree is to reach the successor path is unique, that if a node can not go to the sub-node, then the sub-node will not be considered.

Some nodes cannot go through its sub-nodes, and some may leave some points after his child node. affect the number of times is the current node points, because to go to the child node is bound to come back, enter this node to spend this node a point, the remaining points is the maximum number of times to go to the child node, but there may be the remaining points. This can be done by defining a dp[i] that represents the maximum value that is obtained from it and its descendants after taking a point into the I node, according to which the dp[i of the node I can go to is at least 1, and the cost is 1, if there are remaining points, for the parent node of I, want to get the remaining points, Spend a 1 pips to get 1 points, not better than dp[i], so choose dp[i], for the same DP value preference for the big one.

The transfer equation is dp[i] = {dp[j]}+cnt*2,| {Dp[j]}|==min (k[i]-1,|{ j}|), | {j}| represents the descendant points,

When k[i]-1>| {j}| can choose to finish the DP value of descendants, then consider selecting the remaining points,

CNT is the minimum number of points left after the child node and the remaining points of the descendant nodes, cnt = min (k[u]-1-|{ J}|,sum (Left (j))). Left (j) is the number of points remaining after J calculates Dp[j].

Also maintain the left (i) when transferring. The point that cannot be reached is not considered.

#include <bits/stdc++.h>using namespacestd;Const intMAXN = 1e5+5; typedefLong Longll;intk[maxn];ll D[maxn];vector<int>G[MAXN];#definePB push_backBOOLcmpintAintb) {returnA >b;} LL DP (intUintFA) { if(d[u]>0)returnD[u]; K[u]--; if(! G[u].size () | | !K[u]) { returnD[u] =1; } Vector<ll>opt; intCNT =0; for(inti =0; I < (int) G[u].size (); i++){ intv =G[u][i]; if(v = = FA | |!k[v])Continue; Opt. PB (DP (V,U)); CNT+=K[v]; } if(!opt.size ())returnD[u] =1; intm = min (K[u], (int) opt.size ()); Nth_element (Opt.begin (), Opt.begin ()+m,opt.end (), CMP); K[u]-=m; D[u]=m; for(inti =0; I < m; i++) {D[u]+=Opt[i]; } if(k[u]>0) {m=min (k[u],cnt); K[u]-=m; D[u]+ = m<<1; } return++d[u];}intMain () {//freopen ("In.txt", "R", stdin); intN scanf"%d",&N); for(inti =1; I <= N; i++) scanf ("%d", K +i); for(inti =1; I < n; i++){ intU,v; scanf"%d%d",&u,&v); G[u]. PB (v); G[V]. PB (U); } intS scanf"%d",&s); K[s]++; printf ("%i64d\n", DP (s,-1)-1); return 0;}

Codeforces 77C Beavermuncher-0xff