#include<bits/stdc++.h>
using namespace std;
const int mo=10007;
#define maxm 200010
#define ll long long
ll w[maxm];
vector<int>G[maxm];
struct node{
    ll v,sum1,sum2;
}f[maxm],ne[maxm];

void dfs(int u,int pr){
	vector<int>S;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i];
		if(pr==v)continue;
        dfs(v,u);
		S.push_back(v);
        ne[u].sum1=(ne[u].sum1+w[v])%mo;
        ne[u].v=max(ne[u].v,w[v]);
        f[u].v=max(f[u].v,ne[v].v);
        f[u].sum1=(f[u].sum1+ne[v].sum1);
	}
    ll maxv=0;
    int sum=0;
    for(int i=0;i<S.size();i++){
        int v=S[i];
        f[v].sum2=(f[v].sum2+sum)%mo;
        f[v].v=max(f[v].v,maxv);
        sum=(sum+w[v])%mo;
        maxv=max(maxv,w[v]);
    }
    maxv=0;sum=0;
	for(int i=S.size()-1;i>=0;i--){
        int v=S[i];
        f[v].sum2=(f[v].sum2+sum)%mo;
        f[v].v=max(f[v].v,maxv);
        sum=(sum+w[v])%mo;
        maxv=max(maxv,w[v]);
    }
    
	
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int x,y;
		cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++) cin>>w[i];
	dfs(1,0);
    ll maxv=0,sum=0;
	for(int i=1;i<=n;i++){
        maxv=max(maxv,w[i]*f[i].v);
        sum=(sum+f[i].sum1*2*w[i]+w[i]*f[i].sum2)%mo;
    }
    cout<<maxv<<' '<<sum;
	return 0;
}

这道题类似于树形dp

先求出每个点的最大联合权值以及每个点相关的权值对的和,然后max即可