我们枚举中间点,当连的点数不小于2时进行处理
最大值好搞
求和:设中间点 i 所连所有点权之和为sum
则对于每个中间点i的联合权值之和为:
w[j]*(sum-w[j])之和
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int p=10007,N=200010,M=400020; 5 int head[M],next[M],to[M],du[N],a[N],size; 6 int w[N],n,sum,ss,m1,m2,ans1,ans2; 7 void uni(int x,int y){ 8 size++; 9 du[x]++; 10 next[size]=head[x]; 11 head[x]=size; 12 to[size]=y; 13 } 14 int main(){ 15 int x,y,q; 16 size=ans1=0; 17 scanf("%d",&n); 18 for (int i=1;i<n;i++){ 19 scanf("%d %d",&x,&y); 20 uni(x,y); 21 uni(y,x); 22 } 23 for (int i=1;i<=n;i++) 24 scanf("%d",&w[i]); 25 for (int x=1;x<=n;x++){ 26 if (du[x]<2) 27 continue; 28 m1=m2=sum=q=ss=0; 29 for (int e=head[x];e;e=next[e]){ 30 int y=to[e]; 31 sum=(sum+w[y])%p; 32 a[++q]=y; 33 if (w[y]>m1){ 34 m2=m1; 35 m1=w[y]; 36 } 37 else if (w[y]>m2) 38 m2=w[y]; 39 } 40 if (m1*m2>ans1) 41 ans1=m1*m2; 42 for (int j=1;j<=q;j++) 43 ans2=(ans2+w[a[j]]*(sum-w[a[j]]+p)%p)%p; 44 } 45 printf("%d %d",ans1,ans2); 46 return 0; 47 }