很容易想到树形dp
设dp[u]表示以u为根所形成的最大联通量
这样设的好处在于只用管理u的儿子到底选或是不选,不用考虑连通性!
转移:
设v为u的一个儿子
if(dp[to]+w>0)
只要大于零就能产生贡献,只要产生贡献就能选
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=1e5+5;
ll dp[maxn];
vector<int>Q[maxn];
vector<ll>w[maxn];
int n;
void dfs(int u,int fa){
for(int i=0;i<Q[u].size();i++){
int to=Q[u][i];
if(to==fa)continue;
dfs(to,u);
if(dp[to]+w[u][i]>0)dp[u]+=dp[to]+w[u][i];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&dp[i]);
for(ll i=1,a,b,c;i<n;i++){
scanf("%lld%lld%lld",&a,&b,&c);
Q[a].push_back(b);
Q[b].push_back(a);
w[a].push_back(c);
w[b].push_back(c);
}
dfs(1,-1);
ll ans=-1e18;
for(int i=1;i<=n;i++)
ans=max(ans,dp[i]);
cout<<ans<<endl;
return 0;
}