题目:
给出一棵树,求大两棵子树权重和。
题解:
我今天心情本来是烦躁的,想刷两题水题解闷……结果卡题了!!!我现在的心情是暴躁的!!
我们扯一会儿题解。
首先dfs一遍把每个点的权重算出来肯定能想到。
然后开始考虑如何维护“两个”子树的最大值。
后来发现自己傻逼了只需要维护一个子树的最大值就行了。
dp[i]表示i号节点的最大子树权重和。
j表示i的孩子。
dp[i]=max(所有dp[j],dp[i])
然后WA了。
发现判断叶子节点的时候没有特判根节点。
然后WA了。
发现是没有设long long。
然后WA了。
发现是最大值初始化不够小。
然后过了。
想摔桌子,砸墙壁。。
#include<iostream>
#include<vector>
using namespace std;
const long long INF=1e18+1;
long long n;
long long arr[201000];
long long weight[201000];
long long dp[201000];
vector<long long> vec[201000];
long long ans=-INF;
void getweight(long long fa,long long x){
if(vec[x].size()==1&&x!=1){
weight[x]=arr[x];
return ;
}
long long all=arr[x];
for(long long i=0;i<vec[x].size();i++){
long long to=vec[x][i];
if(to==fa) continue;
getweight(x,to);
all+=weight[to];
}
weight[x]=all;
}
void getdp(long long fa,long long x){
if(vec[x].size()==1&&x!=1){
dp[x]=weight[x];
return ;
}
dp[x]=weight[x];
long long bit=0;
long long max1=-INF;
long long max2=-INF;
for(long long i=0;i<vec[x].size();i++){
long long to=vec[x][i];
if(to==fa) continue;
getdp(x,to);
if(dp[to]>max1){
max2=max1;
max1=dp[to];
}
else if(dp[to]>max2){
max2=dp[to];
}
dp[x]=max(dp[x],dp[to]);
}
if(max1!=-INF&&max2!=-INF&&max1+max2>ans){
ans=max1+max2;
}
}
int main(){
cin>>n;
for(long long i=1;i<=n;i++){
cin>>arr[i];
}
for(long long i=0;i<n-1;i++){
long long a,b;
cin>>a>>b;
vec[a].push_back(b);
vec[b].push_back(a);
}
getweight(0,1);
getdp(0,1);
if(ans==-INF) cout<<"Impossible"<<endl;
else cout<<ans<<endl;
}