E78 树上背包 P1273 有线电视网

视频链接:E78 树上背包 P1273 有线电视网_哔哩哔哩_bilibili

 

 

P1273 有线电视网 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 树上背包 O(n*m)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int read(){
  int x=0,f=1;char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  while('0'<=ch && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  return x*f;
}
const int N=3010;
int idx,head[N];
struct E{int to,w,ne;}e[N*N];
void add(int u,int v,int w){
  e[++idx]={v,w,head[u]};head[u]=idx;
}
int n,m;
int val[N],s[N],f[N][N];

void dfs(int u){
  if(u>n-m){f[u][1]=val[u]; s[u]=1; return;}
  for(int i=head[u];i;i=e[i].ne){
    int v=e[i].to;
    dfs(v);
    s[u]+=s[v];
    for(int j=s[u];j>=0;j--)
      for(int k=0;k<=min(j,s[v]);k++)
        f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]-e[i].w);
  }
}
int main(){
  n=read(),m=read();
  for(int u=1;u<=n-m;u++){
    int k=read();
    for(int j=1;j<=k;j++){
      int v=read(),w=read();
      add(u,v,w);
    }
  }
  for(int i=n-m+1;i<=n;i++)val[i]=read();
  memset(f,~0x3f,sizeof(f));  
  for(int i=1;i<=n;i++) f[i][0]=0;
  dfs(1);
  for(int i=m;i>=0;i--)
    if(f[1][i]>=0){printf("%d",i); break;}
}

 

// 树上背包 O(n*m)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int read(){
  int x=0,f=1;char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  while('0'<=ch && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  return x*f;
}
const int N=3010;
int idx,head[N];
struct E{int to,w,ne;}e[N*N];
void add(int u,int v,int w){
  e[++idx]={v,w,head[u]};head[u]=idx;
}
int n,m;
int val[N],s[N],f[N][N];

void dfs(int u){
  if(u>n-m){f[u][1]=val[u]; s[u]=1; return;}
  for(int i=head[u];i;i=e[i].ne){
    int v=e[i].to;
    dfs(v);
    for(int j=s[u];j>=0;j--)
      for(int k=0;k<=s[v];k++)
        f[u][j+k]=max(f[u][j+k],f[u][j]+f[v][k]-e[i].w);
    s[u]+=s[v];
  }
}
int main(){
  n=read(),m=read();
  for(int u=1;u<=n-m;u++){
    int k=read();
    for(int j=1;j<=k;j++){
      int v=read(),w=read();
      add(u,v,w);
    }
  }
  for(int i=n-m+1;i<=n;i++)val[i]=read();
  memset(f,~0x3f,sizeof(f));  
  for(int i=1;i<=n;i++) f[i][0]=0;
  dfs(1);
  for(int i=m;i>=0;i--)
    if(f[1][i]>=0){printf("%d",i); break;}
}

 

posted @ 2024-11-05 22:02  董晓  阅读(40)  评论(0编辑  收藏  举报