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;
}
原文地址:https://www.cnblogs.com/Crossea/p/13740580.html