题意:
就是给你一个树,然后每个节点和每条边都有一个权值,问你选择一个非空的连通块,这个连通块的最大权值和是多少。
思考:
一看就是树上dp一下就行了,刚开始卡了下直接在dfs去更新选择他的儿子节点,也就是dp[now] = max(dp[now],dp[spot]),但是我还更新了dp[now] = max(dp[now],dp[now]+dp[spot]+w),这样就会导致,你选择了一个儿子节点,但是又同时选了另一个连通块,但是没加那条边。所以其实对于直接选儿子节点,可以每次dfs完之后更新一下即可,因为这个题也没说初始点必须是1。然后还有值得注意的就是有负值,所以刚开始的maxn赋值为负无穷。
和我之前做的一道题差不多:Rinne Loves Edges。
代码:
int T,n,m,k;
int va[N];
int dp[N];
int maxn = -inf;
vector<PII > e[N];
void dfs(int now,int p)
{
dp[now] = va[now];
for(auto t:e[now])
{
int spot = t.fi,w = t.se;
if(spot==p) continue;
dfs(spot,now);
dp[now] = max(dp[now],dp[now]+dp[spot]+w);
}
maxn = max(maxn,dp[now]);
}
signed main()
{
IOS;
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i];
for(int i=1;i<n;i++)
{
int a,b,c;
cin>>a>>b>>c;
e[a].pb({b,c});
e[b].pb({a,c});
}
for(int i=1;i<=n;i++) dp[i] = -inf;
dfs(1,0);
cout<<maxn;
return 0;
}
总结:
注意细节呀。