联合权值
首先,直接两重循环暴力枚举得了70分
然后发现第二重循环可以记忆化一下
记忆一下每个点的子节点的权值和、最大值、
次大值(为了处理该点的父节点权值恰好为最大值)
具体看代码
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define N 400010 6 #define int long long 7 int n,w[N],Head[N],tot; 8 int Max,Sum,sum[N],max1[N],max2[N]; 9 inline int read(){ 10 int x=0; char c=getchar(); 11 while(c<'0'||c>'9') c=getchar(); 12 while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } 13 return x; 14 } 15 struct NODE{ 16 int to,next; 17 } e[N<<1]; 18 inline void add(int x,int y){ 19 e[++tot].to=y; 20 e[tot].next=Head[x]; 21 Head[x]=tot; 22 } 23 #undef int 24 int main() 25 #define int long long 26 { 27 n=read(); 28 int x,y; 29 for(int i=1;i<n;i++){ 30 x=read(); y=read(); 31 add(x,y); add(y,x); 32 } 33 for(int i=1;i<=n;i++) 34 w[i]=read(); 35 for(int i=1;i<=n;i++) 36 for(int j=Head[i];j;j=e[j].next){ 37 int son=e[j].to; 38 if(!sum[son]&&!max1[son]) 39 for(int k=Head[son];k;k=e[k].next){ 40 int gson=e[k].to; 41 if(max2[son]<w[gson]){ 42 max2[son]=w[gson]; 43 if(max2[son]>max1[son]) 44 swap(max1[son],max2[son]); 45 } 46 sum[son]+=w[gson]; 47 } 48 if(w[i]!=max1[son]) 49 Max=max(Max,max1[son]*w[i]); 50 else Max=max(Max,max2[son]*w[i]); 51 Sum=(Sum+(sum[son]-w[i])*w[i])%10007; 52 } 53 printf("%lld %lld",Max,Sum); 54 return 0; 55 }