標籤:span line open stream size 傳送門 names ble i++
傳送門思路:
任意找一個點為樹根。DFS 遍曆樹,如果子樹和為負就直接跳過,不然就統計進答案。( 雖是任意取一點為根,但不一定從這個點出發能夠取得最優解,要開一個 ans 記錄一下最大值。)
標程:
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#include<string>#include<cstdlib>#include<stack>#include<vector>#include<queue>#include<deque>#include<map>#include<set>using namespace std;#define lck_max(a,b) ((a)>(b)?(a):(b))#define lck_min(a,b) ((a)<(b)?(a):(b))#define maxn 16002typedef long long LL;LL sum[maxn],n;LL head[maxn<<1],cnt=0;vector<LL>son[maxn];LL w[maxn],ans=-maxn;struct hh{ LL nex,to;}t[maxn<<1];inline LL read(){ LL kr=1,xs=0; char ls; ls=getchar(); while(!isdigit(ls)) { if(!(ls^45)) kr=-1; ls=getchar(); } while(isdigit(ls)) { xs=(xs<<1)+(xs<<3)+(ls^48); ls=getchar(); } return xs*kr;}LL u,v;inline void add(LL nex,LL to){ t[++cnt].nex=head[nex]; t[cnt].to=to; head[nex]=cnt;}inline void dfs(LL u,LL fa){ for(LL i=head[u];i;i=t[i].nex) { LL v=t[i].to; if(v==fa) continue; son[u].push_back(v); dfs(v,u); } if(son[u].size()) { for(LL j=0;j<son[u].size();j++) { if(w[son[u][j]]<0) continue; w[u]+=w[son[u][j]]; } } w[u]+=sum[u]; ans=lck_max(ans,w[u]);return ;}int main(){ //freopen("t.in","r",stdin); n=read(); for(LL i=1;i<=n;i++) sum[i]=read(); for(LL i=1;i<n;i++) { u=read();v=read();add(u,v);add(v,u); } dfs(1,0); printf("%lld\n",ans);return 0;}
P1122 最大子樹和