/*/ 题意: 有N个村庄,每个村庄有一个权值,有n-1条路,将村庄连起来,然后选取这些路中的一个联通图,权值最大。 整个图都被联通,找其中权值最大的子联通块。 树状DP。 代码风格学了某个学长的写了个结构体,真刺激。。
AC代码: /*/
#include"algorithm" #include"iostream" #include"cstring" #include"cstdlib" #include"cstdio" #include"string" #include"vector" #include"queue" #include"cmath" using namespace std; typedef long long LL ; #define memset(x,y) memset(x,y,sizeof(x)) #define memcpy(x,y) memcpy(x,y,sizeof(x)) #define FK(x) cout<<"["<<x<<"] " #define bigfor(x) for(LL qq=1;qq<= T ;qq++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int MX = 16666; struct Treedp { struct Edge { int v,nxt; } E[MX<<1]; int Head[MX],erear; bool vis[MX]; int dp[MX]; int INF=-1e9-1e5; void init() { erear=0; memset(E,0); memset(vis,0); memset(Head,-1); } void add(int u,int v) { E[erear].v=v; E[erear].nxt=Head[u]; Head[u]=erear++; } int run(int u) { vis[u]=1; for(int i=Head[u]; ~i; i=E[i].nxt) { int v=E[i].v; if(!vis[v]) { dp[u]+=max(0,run(v)); } } return dp[u]; } void print(int n) { for(int i=1; i<=n; i++) cout<<dp[i]<<" "; puts(""); } }; Treedp tdp; int main() { int n,l,r; scanf("%d",&n); tdp.init(); for(int i=1; i<=n; i++) { scanf("%d",&tdp.dp[i]); } for(int i=1; i<n; i++) { scanf("%d%d",&l,&r); tdp.add(l,r); tdp.add(r,l); } int maxx=-1e9-1000000; tdp.run(1); for(int i=1; i<=n; i++) { maxx=max(maxx,tdp.dp[i]); } // tdp.print(n); printf("%d ",maxx); return 0; }