/* 依赖背包 dp[i][j]表示i结点为根的树选择j个用户时的最大剩余费用 即背包容量是j,价值是最大费用 */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define maxn 3050 struct Edge{int to,nxt,w;}edge[maxn<<1]; int n,m,k,head[maxn],tot,num[maxn],dp[maxn][maxn]; void init(){ memset(head,-1,sizeof head); tot=0; } void addedge(int u,int v,int w){ edge[tot].to=v;edge[tot].w=w;edge[tot].nxt=head[u]; head[u]=tot++; } void dfs(int u,int pre){ for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(v==pre)continue; dfs(v,u); num[u]+=num[v]; } for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(v==pre)continue; for(int j=num[u];j>=0;j--) for(int t=0;t<=num[v];t++) dp[u][j]=max(dp[u][j],dp[u][j-t]+dp[v][t]-edge[i].w); } //printf("%d %d\n",u,dp[u][1]); } int main(){ int v,w; while(cin>>n>>m){ init(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)dp[i][j]=-0x3f3f3f3f; for(int i=1;i<=n-m;i++){// cin>>k; while(k--){ cin>>v>>w; addedge(i,v,w); addedge(v,i,w); num[i]=0; } } for(int i=n-m+1;i<=n;i++) num[i]=1,cin>>dp[i][1]; dfs(1,0); for(int j=m;j>=0;j--) if(dp[1][j]>=0){ printf("%d\n",j); break; } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。