Channel
Test instructions: Edge tree, there are M points is dangerous, now want to divide the tree into m block so that there is just one dangerous point in each block, ask the minimum cost is how much
Ideas:
Dp[i][0|1 with the I node as the root node of the subtree, I is located in the connected block without (there) the minimum cost of the dangerous node;
If I is a leaf node: If I is a danger point dp[i][0] = inf,dp[i][1]= 0; otherwise dp[i][0] = dp[i][1] = 0;
If I is not a leaf node: If I is dangerous point dp[i][0] = inf, dp[i][1] = Sigma min (dp[son][0],dp[son][1]+w);
otherwise dp[i][0] = Sigma min (dp[son][0],dp[son][1]+w), dp[i][1] = min (dp[i][0]–min (dp[son][0],dp[son][1]+w) +dp[son][1]).
Code:
#include <iostream>#include<cstdio>#include<memory.h>#defineMIN (A, B) ((a) < (b)? (a): (b))using namespacestd;Const__int64 inf = 1LL << $;Const intMAXN =100002;structnode{intv; __int64 W; intNext;} EDGE[MAXN<<1];intHead[maxn];__int64 dp[maxn][2];BOOLMACHINE[MAXN];intN,m,idx;voidinit () {memset (head,-1,sizeof(head)); memset (Machine,false,sizeof(machine)); IDX=0; return;}voidAddedge (intUintV,__int64 W) {EDGE[IDX].V=v; EDGE[IDX].W=W; Edge[idx].next=Head[u]; Head[u]= idx++; EDGE[IDX].V=u; EDGE[IDX].W=W; Edge[idx].next=Head[v]; HEAD[V]= idx++; return;}voidRead () {scanf ("%d%d",&n,&m); intu,v; __int64 W; for(intI=1; i<n;i++) {scanf ("%d%d%i64d",&u,&v,&W); Addedge (U,V,W); } for(intI=0; i<m;i++) {scanf ("%d",&T); Machine[u]=true; } return;}voidDfsintStintpre) { BOOLleaf =true; for(intI=head[st];i! =-1; i=Edge[i].next) { if(EDGE[I].V = = pre)Continue; Leaf=false; DFS (EDGE[I].V, ST); } if(leaf) {dp[st][0] = Machine[st]? Inf:0; dp[st][1] =0; return; } if(Machine[st]) {dp[st][0] =inf; dp[st][1] =0; for(intI=head[st];i! =-1; i=Edge[i].next) { if(EDGE[I].V = = pre)Continue; dp[st][1] + = MIN (dp[edge[i].v][0], EDGE[I].W + dp[edge[i].v][1]); } } Else{dp[st][0] =0; dp[st][1] =inf; for(intI=head[st];i! =-1; i=Edge[i].next) { if(EDGE[I].V = = pre)Continue; dp[st][0] + = MIN (dp[edge[i].v][0], EDGE[I].W + dp[edge[i].v][1]); } for(intI=head[st];i! =-1; i=Edge[i].next) { if(EDGE[I].V = = pre)Continue; dp[st][1] = MIN (dp[st][1], dp[st][0]-MIN (dp[edge[i].v][0], EDGE[I].W + dp[edge[i].v][1]) + dp[edge[i].v][1]); } } return;}intMain () {intCAs; scanf ("%d",&CAs); while(cas--) {init (); Read ();; DFS (0,-1); printf ("%i64d\n", MIN (dp[0][0], dp[0][1])); } return 0;}
View Code
"Tree dp" HDU 4313 Matrix