我们枚举中间点,当连的点数不小于2时进行处理
最大值好搞
求和:设中间点 i 所连所有点权之和为sum
则对于每个中间点i的联合权值之和为:
w[j]*(sum-w[j])之和
#include<cstdio>
#include<cstring>
using namespace std;
const int p=,N=,M=;
int head[M],next[M],to[M],du[N],a[N],size;
int w[N],n,sum,ss,m1,m2,ans1,ans2;
void uni(int x,int y){
size++;
du[x]++;
next[size]=head[x];
head[x]=size;
to[size]=y;
}
int main(){
int x,y,q;
size=ans1=;
scanf("%d",&n);
for (int i=;i<n;i++){
scanf("%d %d",&x,&y);
uni(x,y);
uni(y,x);
}
for (int i=;i<=n;i++)
scanf("%d",&w[i]);
for (int x=;x<=n;x++){
if (du[x]<)
continue;
m1=m2=sum=q=ss=;
for (int e=head[x];e;e=next[e]){
int y=to[e];
sum=(sum+w[y])%p;
a[++q]=y;
if (w[y]>m1){
m2=m1;
m1=w[y];
}
else if (w[y]>m2)
m2=w[y];
}
if (m1*m2>ans1)
ans1=m1*m2;
for (int j=;j<=q;j++)
ans2=(ans2+w[a[j]]*(sum-w[a[j]]+p)%p)%p;
}
printf("%d %d",ans1,ans2);
return ;
}
STD