E95 01分数规划+树上背包 P1642 规划

视频链接:E95 01分数规划+树上背包 P1642 规划_哔哩哔哩_bilibili

 

 

A07 01分数规划 - 董晓 - 博客园 (cnblogs.com)

P1642 规划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

复制代码
// 01分数规划+树上背包 复杂度:n*m*log(1e9)
#include <bits/stdc++.h>
using namespace std;

int read(){
  int x=0,f=1;char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=x*10+c-'0';c=getchar();}
  return f*x;
}
const int N=105,Inf=1<<30;
int head[N],idx;
struct E{int to,ne;}e[N<<1];
int n,m,a[N],b[N],sz[N];
double c[N],f[N][N];

void add(int u,int v){
  e[++idx]={v,head[u]};
  head[u]=idx;
}
void dfs(int u,int fa){
  sz[u]=1; f[u][0]=0;
  for(int i=head[u];i;i=e[i].ne){
    int v=e[i].to;
    if(v==fa) continue;
    dfs(v,u);
    sz[u]+=sz[v];
    for(int j=min(m,sz[u]);j>=0;j--) //容量
      for(int k=0;k<=min(j,sz[v]);k++) //决策
        f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);
  }
  for(int i=min(m,sz[u]);i>0;i--) f[u][i]=f[u][i-1]+c[u];
}
bool check(double x){
  for(int i=1;i<=n;i++) 
    for(int j=0;j<=m;j++) f[i][j]=-Inf;
  for(int i=1;i<=n;i++) c[i]=a[i]-x*b[i];
  dfs(1,0);
  for(int i=1;i<=n;i++) if(f[i][m]>=0) return 1;
  return 0;
}
int main(){
  n=read(),m=read();
  for(int i=1;i<=n;i++) a[i]=read();
  for(int i=1;i<=n;i++) b[i]=read();
  m=n-m;
  for(int i=1;i<n;i++){
    int a=read(),b=read();
    add(a,b); add(b,a);
  }
  double l=0,r=1000000;
  while(r-l>1e-3){
    double mid=(l+r)/2;
    if(check(mid)) l=mid;
    else r=mid;
  }
  printf("%.1lf\n",l);
}
复制代码

 

posted @   董晓  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示