2020.7.22 T1三色树(jz暑假训练day7)

这是一道关于无根树的题目,要求通过割除一些边,使得形成的树满足合法条件:没有黑色节点或者最多有一个白色节点。题目提供了输入输出格式、样例输入输出以及数据约束,并指出在满足一定条件的情况下,需要使用树型动态规划解决,并注意避免深度搜索导致的系统栈溢出问题。
摘要由CSDN通过智能技术生成

Description

给出一个N个节点的无根树,每条边有非负边权,每个节点有三种颜色:黑,白,灰。
一个合法的无根树满足:树中不含有黑色结点或者含有至多一个白色节点。
现在希望你通过割掉几条树边,使得形成的若干树合法,并最小化割去树边权值的和。

Input

第一行一个正整数N,表示树的节点个数。
第二行N个整数Ai,表示i号节点的颜色,0 表示黑色,1表示白色,2表示灰色。
接下来N-1行每行三个整数Xi Yi Zi,表示一条连接Xi和Yi权为Zi的边。

Output

输出一个整数表示其最小代价。

Sample Input

5
0 1 1 1 0
1 2 5
1 3 3
5 2 5
2 4 16

Sample Output

10
样例解释:
花费10的代价删去边(1, 2)和边(2, 5)。

Data Constraint

20%的数据满足N≤10。
另外30%的数据满足N≤100,000,且保证树是一条链。
100%的数据满足N≤300,000,0≤Zi≤1,000,000,000,Ai∈{0,1,2}。

赛时

蒟蒟表示连20分暴力都没打出

正解

十分显然的树型dp,设f[i][0]表示以i为根的子树,除去已经割去的部分,满足没有黑色节点的最小代价; f[i][1]则表示没有白色
节点的最小代价;f[i][2]则表示有1或 0个白色节点的最小代价。
在这里插入图片描述
方程如上,自行理解,不多阐述。
之后有个恶心的东东是这道题用深搜会boom,boom,boom,系统栈会爆掉,所以要人工栈(自食其力,丰衣足食)

代码

#include<cstdio>
#include<cstring>
#define N 300007
using namespace std;
const long long INF=1e17;//ans会很大,所以“无穷大”也要很大
int n,cnt,a[N],head[N],d[N],fa[N];
long long f[N][3];
bool bz[N];
struct tree{
   
	int to,nxt;
	long long w;
}e[N<<2];
void add(int u,int v,long long w){
   //链式前向星
	e[++cnt].to=v;
	e[cnt].w=w;
	e[cnt].nxt=head[u];
	head[u]=cnt
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值