zoukankan      html  css  js  c++  java
  • 【BZOJ1812】riv(多叉树转二叉树,树形DP)

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

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

    思路:见IOI2005龙凡解题报告

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

    dp[i,j,k]表示以i为根的子树,建j个节点,离i最近的被选点是k时的最小总和

    [ dp[i,j,k]=minegin{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.
  • 相关阅读:
    Jenkins插件管理及汉化
    rpm安装Jenkins报错
    Codeforces Round #572 (Div. 2) A.
    [kuangbin带你飞]专题一 简单搜索 A棋盘问题
    北京信息科技大学第十一届程序设计竞赛(重现赛)I
    北京信息科技大学第十一届程序设计竞赛(重现赛)H
    北京信息科技大学第十一届程序设计竞赛(重现赛)B
    nyoj 206-矩形的个数 (a*b*(a+1)*(b+1)/4)
    nyoj 241-字母统计 (python count)
    nyoj 242-计算球体积 (pi*r*r*r*4/3)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6203616.html
Copyright © 2011-2022 走看看