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.
  • 相关阅读:
    nginx源码分析——http模块
    linux 信号处理
    文件读写监控(inotify, systemtap)
    rem
    vscode 将本地项目上传到码云
    vue 模拟去哪网
    form 文件上传
    分页
    修改默认select样式
    模拟select下拉框、复选框效果
  • 原文地址:https://www.cnblogs.com/myx12345/p/6203616.html
Copyright © 2011-2022 走看看