築巢(牛客)
阿新 • • 發佈:2022-03-09
很容易想到樹形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; }