Test instructions: given a tree, each point has a value, and each edge has a Benquan (one-way edge). You can select K black dots to minimize the sum of the costs (distance * points) from each point to the black dots closest to him.
n<=100 k<=50 w[i],a[i]<=10000
Ideas: See IOI2005 Ronfain Problem Solving report
A tree-shaped DP from father to son.
Why do you want to turn two forks in multiple forks? Because the false point U is chosen, the selected point will only affect you own son, the brother of U has no influence
Dp[i,j,k] Represents a subtree with the root of I, J nodes, and the nearest selected point of I is the smallest sum of K
\[dp[i,j,k]=min\begin{cases} dp[l[i],t,k]+dp[r[i],j-t,k]+ (Dis[i]-dis[k]) *a[i]\\dp[l[i],t,i]+dp[r[i],j-t-1,k] \ End{cases} \]
1 varDp:Array[1.. $,0.. -,1.. $] ofLongint;2Head,vet,next,len,l,r,tree,a,dis:Array[1.. +] ofLongint;3 N,m,i,x,y,tot:longint;4 5 procedureAdd (a,b,c:longint);6 begin7 Inc (TOT);8next[tot]:=Head[a];9vet[tot]:=b;Tenlen[tot]:=C; Onehead[a]:=tot; A End; - - procedureDFS (u:longint); the varE,v:longint; - begin -e:=Head[u]; - whileE<>0 Do + begin -v:=Vet[e]; +dis[v]:=dis[u]+Len[e]; A Dfs (v); ate:=Next[e]; - End; - End; - - functionmin (x,y:longint): Longint; - begin in ifX<y Thenexit (x); - exit (y); to End; + - functionAsk (U,i,k:longint): Longint; the varAns,j:longint; * begin $ ifDp[u,i,k]<maxlongintDiv 3 Thenexit (Dp[u,i,k]);Panax NotoginsengDp[u,i,k]:=maxlongintDiv 3; - forj:=0 toI Do the begin +ans:=0; A ifL[u]>0 Thenans:=ans+Ask (l[u],j,k); the ifR[u]>0 ThenAns:=ans+ask (r[u],i-j,k); +Dp[u,i,k]:=min (dp[u,i,k],ans+ (dis[u]-dis[k]) *A[u]); - ifi-j-1>=0 Then $ begin $ans:=0; - ifL[u]>0 Thenans:=ans+Ask (l[u],j,u); - ifR[u]>0 ThenAns:=ans+ask (r[u],i-j-1, k); thedp[u,i,k]:=min (dp[u,i,k],ans); - End;Wuyi End; theWriteln (U1,' 'I' ', K-1); - exit (Dp[u,i,k]); Wu End; - About begin $Assign (input,'bzoj1812.in'); Reset (input); -Assign (output,'Bzoj1812.out'); Rewrite (output); - readln (n,m); - Inc (n); A fori:=2 toN Do + begin the read (a[i],x,y); - Inc (X); $ iftree[x]=0 Then beginL[x]:=i; Tree[x]:=i;End the Else beginR[tree[x]]:=i; Tree[x]:=i;End; the Add (x,i,y); the End; theDfs1); - Fillchar (Dp,sizeof (DP), $7f); inWriteln (Ask (1M1)); the close (input); the close (output); About End.
"BZOJ1812" Riv (Multi-fork tree to two fork tree, tree DP)