联合权值
洛谷P1351 联合权值
数学方法+枚举中间点,因为两两之间都要乘,故等价于(a+b+c)^2-a^2-b^2-c^2.这里用vector存的相连的点。
#include<bits/stdc++.h> #define k 10007 using namespace std; vector<int>v[200010]; int w[200010]; int n,ans,maxn; void in(int &x) { char c=getchar();x=0; while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); } int main() { in(n); int x,y; for(int i=1;i<n;i++) { in(x),in(y); v[x].push_back(y); v[y].push_back(x); } for(int i=1;i<=n;i++) in(w[i]); for(int i=1;i<=n;i++) { int max1=0,max2=0; int l=v[i].size(); if(l>1) { int p=0,q=0; for(int j=0;j<l;j++) { p+=w[v[i][j]]; q+=w[v[i][j]]*w[v[i][j]]; p%=k; q%=k; if(w[v[i][j]]>max1) { max2=max1; max1=w[v[i][j]]; } else if(w[v[i][j]]>max2) max2=w[v[i][j]]; } maxn=max(maxn,max1*max2); ans+=(p*p-q)%k; ans%=k; } } cout<<maxn<<' '<<ans; return 0; }