之前的解题报告无法过全部数据,因邻接表没有优化,统计权值方式也太暴力,做以下修改
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;
}