首页 > 代码库 > 【BZOJ1812】riv(多叉树转二叉树,树形DP)

【BZOJ1812】riv(多叉树转二叉树,树形DP)

题意:给定一棵树,每个点有权值,每条边有边权(单向边)。你可以选取K个黑点,使得从每个点移动到距离他最近的黑点的花费(距离*点权)的总和最小。

n<=100 k<=50 w[i],a[i]<=10000

思路:见IOI2005龙凡解题报告

又是一道从父亲到儿子的树形DP

为什么要多叉转二叉?因为假设点U被选,这个被选点只会对U自己的儿子有影响,对U的兄弟并没有影响

dp[i,j,k]表示以i为根的子树,建j个节点,离i最近的被选点是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 var dp:array[1..200,0..60,1..200]of longint;
 2     head,vet,next,len,l,r,tree,a,dis:array[1..1000]of longint;
 3     n,m,i,x,y,tot:longint;
 4 
 5 procedure add(a,b,c:longint);
 6 begin
 7  inc(tot);
 8  next[tot]:=head[a];
 9  vet[tot]:=b;
10  len[tot]:=c;
11  head[a]:=tot;
12 end;
13 
14 procedure dfs(u:longint);
15 var e,v:longint;
16 begin
17  e:=head[u];
18  while e<>0 do
19  begin
20   v:=vet[e];
21   dis[v]:=dis[u]+len[e];
22   dfs(v);
23   e:=next[e];
24  end;
25 end;
26 
27 function min(x,y:longint):longint;
28 begin
29  if x<y then exit(x);
30  exit(y);
31 end;
32 
33 function ask(u,i,k:longint):longint;
34 var ans,j:longint;
35 begin
36  if dp[u,i,k]<maxlongint div 3 then exit(dp[u,i,k]);
37  dp[u,i,k]:=maxlongint div 3;
38  for j:=0 to i do
39  begin
40   ans:=0;
41   if l[u]>0 then ans:=ans+ask(l[u],j,k);
42   if r[u]>0 then ans:=ans+ask(r[u],i-j,k);
43   dp[u,i,k]:=min(dp[u,i,k],ans+(dis[u]-dis[k])*a[u]);
44   if i-j-1>=0 then
45   begin
46    ans:=0;
47    if l[u]>0 then ans:=ans+ask(l[u],j,u);
48    if r[u]>0 then ans:=ans+ask(r[u],i-j-1,k);
49    dp[u,i,k]:=min(dp[u,i,k],ans);
50   end;
51  end;
52  //writeln(u-1, ,i, ,k-1);
53  exit(dp[u,i,k]);
54 end;
55 
56 begin
57  assign(input,bzoj1812.in); reset(input);
58  assign(output,bzoj1812.out); rewrite(output);
59  readln(n,m);
60  inc(n);
61  for i:=2 to n do
62  begin
63   read(a[i],x,y);
64   inc(x);
65   if tree[x]=0 then begin l[x]:=i; tree[x]:=i; end
66    else begin r[tree[x]]:=i; tree[x]:=i; end;
67   add(x,i,y);
68  end;
69  dfs(1);
70  fillchar(dp,sizeof(dp),$7f);
71  writeln(ask(1,m,1));
72  close(input);
73  close(output);
74 end.

 

【BZOJ1812】riv(多叉树转二叉树,树形DP)