题意:

t组输入,每组数据中n个节点构成一棵树,然后给你n-1条边。给你一个m,然后给你m个k的素数因子,你需要给这n-1条边都赋一个权值,这n-1条边的权值之积应该等于k。如果k的素数因子数量小于n-1,那可以使用1来填充

然后我们定义F(x,y)为节点x到节点y的路径上所有边的和

我们要求出来所有任意两点之间的F(x,y),然后把所有F(x,y)加起来输出,求最大结果是多少,结果取余1e9+7

题解:

因为我们要使

这个尽可能大,所以肯定要按那一条边使用次数最多,我们就把最大那个素数因子给这一条边,这样得到的结果肯定最大

怎么处理每一条边的使用次数,可以使用dfs遍历一遍就可以了

dfs过程中如果遇到叶节点,那么与叶节点相连这条边的使用次数也就是n-1,例如叶节点是1,那么节点1与2,3,4...n这些点构成的路径会经过这条边n-1次

如果不是叶节点,我们首先要在dfs过程中记录一下,这个节点有多少子节点,设为ans,然后ans*(n-ans)就是对与这个节点相连那条边的使用次数

之后再处理一下素数因子,如果素数因子小于n-1,那么就需要补加上n-m+1个1

如果素数因子大于n-1,那么就让多的素数因子乘起来变成一个

dfs的根节点,就随便找一个叶节点就行

代码:

#include<stack>
#include<queue>
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-8;
const int INF = 0x3f3f3f3f;
vector<ll>w[maxn],L;
ll p[maxn],n,root,m;
void add_edge(ll x,ll y)
{
w[x].push_back(y);
w[y].push_back(x);
}
ll dfs(ll x,ll fa)
{
ll len=w[x].size(),ans=0;
if(len==1 && x!=root)
{
L.push_back(n-1);
return 1;
}
for(ll i=0; i<len; ++i)
{
ll y=w[x][i];
if(y==fa) continue;
ll temp=dfs(y,x);
ans+=temp;
}
ans++;
//printf("%lld %lld*****\n",x,1);
//printf("%lld***%lld\n",ans,ans*(n-ans));
if(x!=root)
{ L.push_back(ans*(n-ans));
}
return ans;
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
ll t;
cin>>t;
while(t--)
{
ll m,sum=0;
//num=1;
root=1;
L.clear();
//scanf("%lld",&n);
cin>>n;
for(ll i=1; i<=n; ++i)
w[i].clear();
for(ll i=1; i<n; ++i)
{ ll x,y;
//scanf("%lld%lld",&x,&y);
cin>>x>>y;
add_edge(x,y);
}
//scanf("%lld",&m);
cin>>m;
for(ll i=1; i<=m; ++i)
{
//scanf("%lld",&p[i]);
cin>>p[i];
}
for(ll i=1; i<=n; ++i)
{
if(w[i].size()==1)
{
root=i;
break;
}
}
dfs(root,-1);
sort(p+1,p+1+m,greater<ll>());
sort(L.begin(),L.end(),greater<ll>());
ll d=0;
if (m > n - 1)
{
d = m - n + 1;
for (ll i = 1; i <= d; i++)
{
p[i + 1] = p[i + 1] * p[i] % mod;
}
}
if (m < n - 1)
{
for (ll i = m + 1; i <= n - 1; i++)
{
p[i] = 1;
}
}//printf("*********\n");
sum=0;
for(ll i=1;i<n;++i)
{
//printf("%lld %lld\n",que[i],p[i]);
sum=sum+L[i-1]*p[i+d];
sum = (sum + mod) % mod;
}
cout<<sum<<endl;
}
return 0;
}

Codeforces Round #665 (Div. 2) D - Maximum Distributed Tree dfs贡献记录的更多相关文章

  1. Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree (dfs计数,树)

    题意:给你含有\(n\)个节点,\(n-1\)条边的树,以及\(m\)个质数和\(1\),你需要在这\(m\)个质数和一个\(1\)选择数(质数只能选一次,\(1\)可以多选)给\(n-1\)条边赋值 ...

  2. Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree 题解(贪心+易错)

    题目链接 题目大意 给你一课树,要你给每一条边分权值,每条边的权值大于0,他们的乘积等于k,而且要使得n-1条边1的数量尽可能少,定义 f(u,v)为u到v的边权和求 \(\max \sum_{i=1 ...

  3. Codeforces Round #665 (Div. 2)

     Codeforces Round #665 (Div. 2)  A. Distance and Axis 如果\(B\)在\(O\)左边,那么只能是定值\(OA\) 如果\(B\)在\(OA\)中间 ...

  4. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  5. Codeforces Round #319 (Div. 1) B. Invariance of Tree 构造

    B. Invariance of Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/576/ ...

  6. Codeforces Round #221 (Div. 1) B. Maximum Submatrix 2 dp排序

    B. Maximum Submatrix 2 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset ...

  7. Codeforces Round #276 (Div. 1) B. Maximum Value 筛倍数

    B. Maximum Value Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/484/prob ...

  8. Codeforces Round #508 (Div. 2) E. Maximum Matching(欧拉路径)

     E. Maximum Matching 题目链接:https://codeforces.com/contest/1038/problem/E 题意: 给出n个项链,每条项链左边和右边都有一种颜色(范 ...

  9. Codeforces Round #172 (Div. 2) D. Maximum Xor Secondary 单调栈应用

    http://codeforces.com/contest/281/problem/D 要求找出一个区间,使得区间内第一大的数和第二大的数异或值最大. 首先维护一个单调递减的栈,对于每个新元素a[i] ...

随机推荐

  1. 虚拟机linux共享文件夹

    linux共享文件夹问题 1. 初配置 2. 挂载 018.7.8 为了实现win7与VMware中linux文件夹共享很花费了一些时间,但终成正果 1. 初配置 虚拟机设置->选项->共 ...

  2. zabbix 监控tomcat

    zabbix 监控tomcat server端rpm -ivh jdk-8u20-linux-x64.rpmvi /etc/profileJAVA_HOME=/usr/java/jdk1.8.0_20 ...

  3. Java-Servlet知识总结

    目录 Servlet概述 为什么要学习Servlet 什么是 Servlet 工作流程 生命周期 处理请求的方法 HttpServletRequest 和 HttpServletResponse Ht ...

  4. LuoguP5488 差分与前缀和

    题意 给定一个长为\(n\)的序列\(a\),求出其\(k\)阶差分或前缀和.结果的每一项都需要对\(1004535809\)取模. 打表找规律 先看前缀和,设\(n=5\),\(k=4\),按照阶从 ...

  5. 二本学生拿到腾讯大厂offer的成长记录

    本人迈莫,是在20年以春招实习生的身份进入鹅厂,经过重重波折,最终成为鹅仔一份子.接下来我会以我亲生经历为例,分享一下普通大学的学生也是可以进去大厂,拭目以待!!! 初入大学 惨遭毒打 时间倒回到17 ...

  6. XV6学习(1) Lab util

    正在学习MIT的6.S081,把做的实验写一写吧. 实验的代码放在了Github上. 第一个实验是Lab util,算是一个热身的实验,没有涉及到系统的底层,就是使用系统调用来完成几个用户模式的小程序 ...

  7. CISCO 如何重置3850交换机密码

    SUMMARY STEPS: Connect a terminal or PC to the switch. Set the line speed on the emulation software ...

  8. Jmeter如何录制APP客户端脚本

    简单五步教大家Jmeter录制APP客户端脚本: Step1 右键单击该测试计划,选择"添加"-"线程组",添加一个线程组. Step2 为了录制客户端的操作, ...

  9. jQuery 真伪数组的转换

    //真数组转换伪数组 var arr = [1,3,5,7,9]; var obj = {}; [].push.apply(obj,arr); console.log(obj) //伪数组转真数组 v ...

  10. gitignore 不起作用的解决办法 不再跟踪 让.gitignore生效,跟踪希望被跟踪的文件

    实践 # https://git-scm.com/docs/gitignore https://git-scm.com/docs/gitignore 不跟踪log目录下的所有文件,但需要保留这个文件夹 ...