zoukankan      html  css  js  c++  java
  • 洛谷 P2015 二叉苹果树

    题目传送门

    树形dp,(f_{i,j})表示以i为根,子树删j条边的最少苹果数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    int n,q,head[101],si[101],m,pp,ans,ss[101],ll[101],oo[101];
    int f[101][101];
    struct kkk {
    	int to,next,v;
    }e[500];
    
    inline void add(int x,int y,int vv) {
    	e[++pp].to = y;
    	e[pp].v = vv;
    	e[pp].next = head[x];
    	head[x] = pp;
    	oo[y]++;
    }
    
    inline int dp(int rt,int fa,int le) {
    	f[rt][0] = 0;
    	if(e[head[rt]].to == fa && oo[rt] == 1) {
    		f[rt][1] = le;
    		si[rt] = 1;
    		return 1;
    	}
    	int sum = 0,len = 0,so[2],tot = -1;
    	for(int i = head[rt];i; i = e[i].next) {
    		int u = e[i].to;
    		if(u == fa) continue;
    		si[rt] += dp(u,rt,e[i].v);
    		so[++tot] = u;
    	}
    	si[rt]++;
    	for(int i = 1;i <= min(m,si[rt] - 1); i++)
    		for(int k = 0;k <= 1; k++)//二叉树,两个儿子 
    			for(int j = 0;j <= si[so[k]]; j++)
    				//因为一共删i条,所以左子树删j条,那右子树就删i-j条 
    				f[rt][i] = min(f[rt][i],f[so[k]][j] + f[so[k^1]][i-j]);
    	if(m >= si[rt]) f[rt][si[rt]] = ll[rt];
    	return si[rt];
    }
    
    inline int dfs(int rt,int fa,int le) {
    	for(int i = head[rt];i; i = e[i].next) {
    		int u = e[i].to;
    		if(u == fa) continue;
    		ll[rt] += dfs(u,rt,e[i].v);
    	}
    	return ll[rt] = ll[rt] + le;
    }
    
    int main() {
    	memset(f,0x3f3f3f,sizeof(f));
    	scanf("%d%d",&n,&q);
    	m = n - q - 1;
    	for(int i = 1;i < n; i++) {
    		int x,y,t;
    		scanf("%d%d%d",&x,&y,&t);
    		add(x,y,t);
    		add(y,x,t);
    		ans += t;
    	}
    	dfs(1,0,0);
    	dp(1,0,0);
    	printf("%d",ans - f[1][m]);
    	//总数减去最少去除量 
    	return 0;
    }
  • 相关阅读:
    将execel表格的数据导入到mysql数据库
    清明听雨
    h5调用底层接口的一些知识
    微信小程序从零开始开发步骤(一)搭建开发环境
    Matplotlib
    Numpy
    pandas
    6 MapReduce的理解
    静态链表
    单链表
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/13663886.html
Copyright © 2011-2022 走看看