P3018 [USACO11MAR] Tree Decoration G 题解

文章解析了P3018USACO比赛中的TreeDecorationG问题,采用贪心算法解决树状装饰问题,通过深度优先搜索确定每个节点的装饰策略,最小化装饰成本。

P3018 [USACO11MAR] Tree Decoration G 题解

模拟赛考到的题,过来发个题解。顺便吐槽一下这题真水,应该放第二题。

解法

刚看到这题我以为是树形 dp,仔细看了看题,发现题中的要求很少,没有依赖关系,没有要求联通,没有后效性,所以考虑贪心。

因为每个节点放装饰的代价都为正数,所以装饰越少越好。我们先去满足一个节点子树的要求,再去看这个节点的要求。分两种情况处理。

  1. 一个节点 iii 的子树的装饰总和不少于 did_idi,则本着不浪费的原则,我们不管这个节点。

  2. 一个节点 iii 的子树的装饰总和少于 did_idi,设其节点中已经有了 mmm 个装饰,则本着不浪费的原则,我们在节点 iii 的子树中找到 cic_ici 最少的点放 di−md_i - mdim 个装饰,这样可以最小化这个点极其祖先的花费。

根据以上两种情况,我们从根节点开始深度优先搜索,按顺序贪心就可以了。

代码

#define int long long
int n,d[100010],c[100010],root,ans,yet[100010];
struct edge
{
	int to;
	edge *next;
};
edge *head[100010];
inline void add(const int &x,const int &y)
{
	edge *e=new edge;
	e->to=y,e->next=head[x],head[x]=e;
}
inline void dfs(int pos,int fa)
{
	for(edge *i=head[pos];i!=nullptr;i=i->next)
		if(i->to!=fa) dfs(i->to,pos),c[pos]=min(c[pos],c[i->to]),yet[pos]+=yet[i->to];
	if(yet[pos]<d[pos]) ans+=(d[pos]-yet[pos])*c[pos],yet[pos]=d[pos];
}
signed main()
{
	read(n);
	for(int i=1,fa;i<=n;i++)
	{
		read(fa),read(d[i]),read(c[i]);
		if(fa==-1) root=i;
		else add(fa,i),add(i,fa);
	}
	dfs(root,0),cout<<ans;
	return 0;
}
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值