原题地址 https://www.luogu.org/problemnew/show/P1351
主要思路:推公式
由上图得到(元素的和的平方)等于(元素的平方和)加(两倍各元素两两相乘)
然后枚举中间点,特判自己不与自己连接
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string.h>
#define mod_base 10007
using namespace std;
const int maxn = 200001;
const int maxm = maxn*2;
const unsigned long long int INF = 2002102002;
int qread() {
int x=0;
char ch=getchar();
while (ch>'9'||ch<'0')ch=getchar();
while (ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int n,en=0,head[maxn],w[maxn],x,y;
long long int ans_s=0,pw_s,s_pw,ans_maxs=0,maxw=0,ans_maxw=0;
struct edge {
int fr,gt,nxt;
};
edge e [maxm];
void adg(int x,int y) {
++en;
e[en].fr=x;
e[en].gt=y;
e[en].nxt=head[x];
head[x]=en;
}
int main() {
//freopen ("1351.in","r",stdin);
//freopen ("1351.out","w",stdout);
n=qread();
memset(head,0,sizeof(head));
for (int i=1; i<n; i++) {
x=qread();
y=qread();
adg(x,y);
adg(y,x);
}
for (int i=1; i<=n; i++)w[i]=qread();
for (int i=1; i<=n; i++) {
maxw=0;
s_pw=pw_s=0;
int js=0;
//cout<<i<<' ';
for (int j=head[i]; j; j=e[j].nxt) {
++js;
//cout<<e[j].gt<<' ';
pw_s=((w[e[j].gt]*w[e[j].gt])+pw_s) % mod_base;
// cout<<w[e[j].gt]<<' '<<pw_s;
s_pw=(s_pw+w[e[j].gt])%mod_base;
if(maxw*w[e[j].gt]>ans_maxw)ans_maxw=maxw*w[e[j].gt];
if(w[e[j].gt]>maxw)maxw=w[e[j].gt];
//cout<<w[e[j].gt]<<' '<<maxw<<endl;
}
if(js>1)ans_s=(ans_s+(s_pw*s_pw-pw_s)) % mod_base;
//cout<<pw_s;
//cout<<endl;
}
cout<<ans_maxw<<' '<<ans_s<<endl;
fclose (stdin);
fclose (stdout);
return 0;
}