大体思路是枚举每个点,把与它距离为2的点都加进来
代码:
#include<cstdio>
#include<iostream>
#define lbw 10007
#define ll long long
const int maxn = 200005;
ll read(){ll ans=0,f=1;char a=getchar();while(a>'9'||a<'0'){if(a=='-')f=-1;a=getchar();}while(a>='0'&&a<='9')ans=(ans<<3)+(ans<<1)+a-'0',a=getchar();return ans*f;}
using namespace std;
ll n,cnt,w[200005],first[maxn],fa[maxn],sw1[maxn],sw2[maxn],ans1,ans2;
ll maxw1[maxn],maxw2[maxn],maxw3[maxn];
struct edge{
ll to,nxt;
}e[2*maxn];
void add(ll u,ll v){
e[++cnt].to=v;
e[cnt].nxt=first[u];
first[u]=cnt;
}
void dfs1(ll now,ll f){
fa[now]=f;
for(int i=first[now];i;i=e[i].nxt){
ll v=e[i].to;
if(v==f)continue;
dfs1(v,now);
}
}
int main(){
n=read();
for(int i=1;i<n;i++){
ll u=read(),v=read();
add(u,v);add(v,u);
}
for(int i=1;i<=n;i++)w[i]=read();
dfs1(1,0);
for(int i=2;i<=n;i++)sw1[fa[i]]=(w[i]+sw1[fa[i]])%lbw;
for(int i=2;i<=n;i++)sw2[fa[i]]=(sw2[fa[i]]+sw1[i])%lbw;
for(int i=2;i<=n;i++){
if(maxw3[fa[i]]<w[i])
if(maxw1[fa[i]]<w[i])maxw1[fa[i]]=w[i];
else maxw3[fa[i]]=w[i];
}
for(int i=2;i<=n;i++)maxw2[fa[i]]=max(maxw2[fa[i]],maxw1[i]);
for(int i=1;i<=n;i++){
ll ans=w[i]*(sw2[i]+max(sw1[fa[i]]-w[i],0ll)+w[fa[fa[i]]])%lbw,awsl=max(maxw2[i],w[fa[fa[i]]]);
if(maxw1[fa[i]]==w[i])awsl=max(maxw3[fa[i]],awsl);
else awsl=max(awsl,maxw1[fa[i]]);
ans1=max(ans1,awsl*w[i]);
ans2=(ans2+ans)%lbw;
}
cout<<ans1<<' '<<ans2%lbw;
return 0;
}