cf 665 DMaximum Distributed Tree
通过dfs搜出每条边会被走过的次数
然后贪心的分配就行
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL mod = 1e9+7;
LL n;
int c = 0;
vector<vector<int> > G;
vector<LL> cnt;
LL dfs(int id, int fa){
LL num = 1;
LL temp = 0;
for(auto e:G[id]){
if(e==fa)
continue;
temp = dfs(e, id);
num += temp;
cnt[c++] = (n-temp)*temp;
}
return num;
}
int main(int argc, char const *argv[])
{
// freopen("in.dat","r", stdin);
ios::sync_with_stdio(false);
int _n;
cin>>_n;
while(_n--){
c = 0;
cin>>n;
G = vector<vector<int> >(n+1);
cnt = vector<LL>(n-1);
int x,y;
LL ans = 0;
rep(i,0,n-1){
cin>>x>>y;
G[x].pb(y);
G[y].pb(x);
}
int m;
cin>>m;
vector<LL> p(m);
dfs(1,-1);
rep(i,0,m) cin>>p[i];
sort(all(p));
sort(all(cnt));
if(m<=n-1){
while(p.size()&&cnt.size()){
ans += (p.back()*cnt.back()%mod)%mod;
ans %= mod;
p.pop_back();
cnt.pop_back();
}
while(cnt.size()){
ans = (ans+cnt.back())%mod;
cnt.pop_back();
}
}else{
rep(i,0,n-2){
ans += (p[i]*cnt[i]%mod)%mod;
ans %= mod;
}
LL temp = cnt.back();
rep(i,n-2,m){
temp = (p[i]*temp)%mod;
}
ans += temp;
}
cout<<ans%mod<<endl;
}
return 0;
}
一条有梦想的咸鱼