CF1401D Maximum Distributed Tree(贪心)

题意:

给出一棵树和一个大数k,请你给这棵树上的每条边分配一个边权,使得这棵树上的节点两两之间的路径总和最大,同时边权中1的数量尽可能少,同时所有边权的乘积等于k。

题解:

一遍DFS处理出每条边对答案的贡献,将边按照贡献从小到大排序,优先把大的因子给贡献大的边。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
const int mod=1e9+7;
int t;
int n;
int m;
ll p[maxn];
int size[maxn];
vector<int> g[maxn];
void dfs (int u,int pre) {
    size[u]=1;
    for (int v:g[u]) {
        if (v==pre) continue;
        dfs(v,u);
        size[u]+=size[v];
    }
}
struct node {
    ll x,y;
    bool operator < (const node &r) const {
        return (ll)x*y>(ll)r.x*r.y;
    }
}Node[maxn];    
bool cmp (int x,int y) {
    return x>y;
}
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) g[i].clear();
        for (int i=1;i<n;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        scanf("%d",&m);
        for (int i=1;i<=m;i++) scanf("%lld",p+i);
        sort(p+1,p+m+1,cmp);
        dfs(1,0);
        int tot=0;
        for (int i=2;i<=n;i++) {
            //printf("%lld %lld\n",n-size[i],size[i]);
            Node[++tot]={(ll)n-size[i],(ll)size[i]}; 
        }
        sort(Node+1,Node+tot+1);
        ll ans=0;
        if (n-1>=m) {
            for (int i=1;i<=m;i++) {
                ans+=(ll)p[i]*Node[i].x*Node[i].y;
                ans%=mod;
            }
            for (int i=m+1;i<=tot;i++) {
                ans+=(ll)Node[i].x*Node[i].y;
                ans%=mod;
            }
        }
        else {
            ll tt=1;
            //printf("1\n");
            //m>=n 
            for (int i=1;i<=(m-n+2);i++) {
                tt*=p[i];
                tt%=mod;
            }
            //printf("%lld\n",tt);
            ans+=(ll)tt*Node[1].x%mod*Node[1].y;
            //printf("%lld\n",ans);
            ans%=mod;
            for (int i=m-n+3;i<=m;i++) {
                ans+=(ll)p[i]*Node[i-(m-n+1)].x*Node[i-(m-n+1)].y;
 
                ans%=mod;
            }
        }
        printf("%lld\n",ans);
    }
} 
 

 

posted @ 2020-08-22 23:56  zlc0405  阅读(347)  评论(0编辑  收藏  举报