zoukankan      html  css  js  c++  java
  • 【题解】有线电视网

    (Question)

    题目大意:给一颗有边权有点权的树,点权为正,边权为负,求出一个连通块,使得其块内权值之和非负,且包含叶子数最多。(点权只在叶子上)

    设计(dp_{i,j})表示第(i)个点,选择(j)个叶子的最大权值。

    那么,枚举每一个点,及其子节点,当递归到底时,(dp[i][1]=v[i]).回溯时,看成背包问题,枚举能选用的最大叶子数目,枚举这个枝条上能选的最多叶子数目,将能选的叶子数目看做物品,最大叶子数目看做容量,做(01)背包即可。

    说实话好久没写树形(dp)了,这种带边权的题着实有点不舒服。

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=3001;
    int n,m,tot,head[MAXN<<1];
    int v[MAXN],dp[MAXN][MAXN];
    int siz[MAXN];
    inline int read(){
    	int s=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')w=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    		s=(s<<1)+(s<<3)+(ch^48);
    		ch=getchar();
    	}
    	return w==-1?-s:s;
    }
    struct edge{
    	int nxt,to,dis;
    }e[MAXN*MAXN];
    inline void add(int x,int y,int w){
    	e[++tot].to=y;
    	e[tot].nxt=head[x];
    	head[x]=tot;
    	e[tot].dis=w;
    }
    int dfs2(int x){
    	if(x>n-m){
    		dp[x][1]=v[x];
    		return 1;
    	}
    	int s=0,t;
    	for(int i=head[x];i;i=e[i].nxt){
    		int j=e[i].to;
    		t=dfs2(j);s+=t;
    		for(int l=s;l>=1;--l){
    			for(int k=1;k<=t;++k){
    				if(l-k>=0)
    					dp[x][l]=max(dp[x][l],dp[x][l-k]+dp[j][k]-e[i].dis);
    			}
    		}
    	}
    	return s;
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n-m;++i){
    		int x=read();
    		for(int j=1;j<=x;++j){
    			int a=read(),b=read();
    			add(i,a,b);
    		}
    	}
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
    			dp[i][j]=-2222;
    	for(int i=1;i<=n;++i)dp[i][0];
    	for(int i=n-m+1;i<=n;++i)v[i]=read();
    	//dfs(1);
    	dfs2(1);
    	for(int i=m;i>=1;--i)
    		if(dp[1][i]>=0){
    			cout<<i<<endl;
    			break;
    		}
    	return 0;
    }
    
  • 相关阅读:
    大战设计模式【13】—— 组合模式
    大战设计模式【12】—— 迭代器模式
    大战设计模式【11】—— 模板方法模式
    大战设计模式【10】—— 外观模式
    linux命令进阶
    ansible普通用户su切换
    Ansible 进阶技巧
    ansible playbook对错误的处理
    ansible示例,离线安装etcd
    (原)centos7安装和使用greenplum4.3.12(详细版)
  • 原文地址:https://www.cnblogs.com/h-lka/p/12601669.html
Copyright © 2011-2022 走看看