之前的解题报告无法过全部数据,因邻接表没有优化,统计权值方式也太暴力,做以下修改
1、建邻接表时加一个数组来记录每个节点的尾指针位置
2、统计每个点周围所有点权值最大的两个点
3、利用x1*y1+x1*y2+x1*y3....=x1*(y1+y2+y3+...)进行简单优化加速
程序如下,完爆官方所有数据:
#include<stdio.h>
#include<stdlib.h>
const int maxn=200010,mod=10007;
struct edge{
int x,next;
};
int w[maxn],s[maxn],last[maxn],max1[maxn],max2[maxn];
struct edge e[maxn*3];
int ans,maxans,k;
void add(int u,int v){
e[++k].x=v;
e[last[u]].next=k;
last[u]=k;
}
int main(){
int i,j,m,n,u,v;
scanf("%d",&n);
k=n;
for(i=1;i<=n;i++){ e[i].x=i; last[i]=i; }
for(i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(i=1;i<=n;i++)scanf("%d",&w[i]);
for(i=1;i<=n;i++)
for(j=e[i].next; j ;j=e[j].next){
m=w[e[j].x];
s[i]=(s[i]+m)%mod;
if(m>max1[i]){
max2[i]=max1[i];
max1[i]=m;
}else if(m>max2[i])
max2[i]=m;
}
for(int i=1;i<=n;i++)
maxans=maxans>max1[i]*max2[i]?maxans:max1[i]*max2[i];
for(i=1;i<=n;i++)
for(j=e[i].next; j ;j=e[j].next){
m=e[j].x;
ans=(ans+w[i]*(s[m]-w[i])%mod+mod)%mod;
}
printf("%d %d\n",maxans,ans);
return 0;
}