ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Luogu3354 河流 - 树形dp -

2022-09-10 14:32:44  阅读:181  来源: 互联网

标签:dep int nd 伐木场 树形 maxn Luogu3354 include dp


题目链接:https://www.luogu.com.cn/problem/P3354

题解:
考虑树形dp
设\(f[i][j][k]\)表示考虑到 i 点,j 是i的祖先中与i最近的伐木场,i及子树中共有 k 个伐木场的最小代价
我们发现,这样设状态无法表示 i 是否有伐木场这个条件,因此钦定 f[][][] 表示 i 没有伐木场,g[][][]表示有

转移发现就是一个树形背包。
如果是 f[][][]的话,最后别忘加上 i 点 到j的贡献
值得一提的是合并答案,注意到i点处理完之后i点是否有伐木场已经不重要了(注意i的子树也已经处理完了),因此可以把 g[][][] 合并到 f[][][],使代码更简洁

// by Balloons
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Madoka"<<endl
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

using namespace std;

typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f, maxn=105;

struct node{
	int to, w;
	node(){}
	node(int to,int w) : to(to), w(w){}
};
int n,m;
vector<node>ve[maxn];
int w[maxn], de[maxn], dep[maxn];
int anc[maxn], sz = 0;
int f[maxn][maxn][maxn], g[maxn][maxn][maxn];

void dfs(int x,int fat = -1){
	anc[++ sz] = x;
	for(node nd : ve[x]){
		int u = nd.to, w = nd.w;
		if(u == fat)continue;
		dep[u] = dep[x] + w;
		dfs(u, x);
		for(int i=1;i<=sz;i++){
			int j = anc[i];
			for(int k = m;k>=0;k--){
				f[x][j][k] += f[u][j][0];
				g[x][j][k] += f[u][x][0];
				
				for(int p = 0;p<=k;p++)
					f[x][j][k] = min(f[x][j][k], f[x][j][p] + f[u][j][k - p]);
				for(int p = 1;p<=k;p++)
					g[x][j][k] = min(g[x][j][k], g[x][j][p] + f[u][x][k - p]);
			}
		}
	}
	
	for(int i = 1;i<=sz;i++){
		int j = anc[i];
		for(int p = 0;p<=m;p++)
			if(p == 0)f[x][j][p] += w[x] * (dep[x] - dep[j]);
			else f[x][j][p] = min(f[x][j][p] + w[x] * (dep[x] - dep[j]), g[x][j][p]);
	}
	-- sz;
}

signed main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int fa;
		scanf("%d%d%d",&w[i],&fa,&de[i]);
		ve[i].push_back(node(fa, de[i]));
		ve[fa].push_back(node(i, de[i]));
	}
	dfs(0);
	printf("%d\n",f[0][0][m]);

	return 0;
}


标签:dep,int,nd,伐木场,树形,maxn,Luogu3354,include,dp
来源: https://www.cnblogs.com/SkyRainWind/p/16676385.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有