题目:https://www.luogu.org/problemnew/show/P1351#sub
一开始想到是树形dp
但不会推公式
后来(看了波题解)恍然大悟
以后做题可以必须先自己模拟。。。不要懒
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxSize=200000,value=10007;
long long a[maxSize+5],anss[maxSize+5],ansm[maxSize+5],vis[maxSize+5],sum[maxSize+5],max0[maxSize+5];
int n;
vector <int> N[maxSize+5];
void dfs(int x)
{
long long i,y,max1,max2;
max1=0; max2=0;
for (i=0;i<N[x].size();i++)
{
y=N[x][i];
if (vis[y]==1)
continue;
vis[y]=1;
sum[x]+=a[y];
if (max0[x]<a[y])
max0[x]=a[y];
if (a[y]>max1)//兄弟
{
max2=max1;
max1=a[y];
}
else if (a[y]>max2)
max2=a[y];
dfs(y);
ansm[x]=max(ansm[x],ansm[y]);//回溯更新
anss[x]+=anss[y];
ansm[x]=max(ansm[x],a[x]*max0[y]);//祖父-孙子
anss[x]+=2*a[x]*sum[y];//祖父-孙子
ansm[x]=max(ansm[x],max1*max2);//兄弟
anss[x]-=a[y]*a[y]; //兄弟
}
anss[x]=(anss[x]+sum[x]*sum[x])%value;
}
int main()
{
int i,x,y;
freopen("a.txt","r",stdin);
scanf("%d",&n);
for (i=0;i<n-1;i++)
{
scanf("%d%d",&x,&y);
N[x].push_back(y);
N[y].push_back(x);
}
for (i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
ansm[i]=0;
}
vis[1]=1;
dfs(1);
printf("%lld %lld",ansm[1],anss[1]);
return 0;
}