https://codeforces.ml/contest/1746/problem/D

题目大意:一棵n节点有根树,根节点为1,分别有两个数组

  s[i] 顶点 i 的魅力值

  c[i] 覆盖顶点 i 的路径数

  每个顶点的路径数必须满足,同一父节点的子节点| c[v1]-c[v2] | <= 1

  问当有k条路径时,∑c[i]*s[i]的最大值

思路:

  因为同一父节点的子节点 | c[v1]-c[v2] | <= 1,所以对于父节点来说,每次都需要平分路径数,如果有多余的路径则考虑

分给贡献最大的前几个节点各一个

  现在对于每个节点有两种状态,平分 or 多获取一个

  f[i][2] 分别表示这两种状态,用优先队列实现选择贡献多的节点,同时加上记忆化搜索防止TLE

 1 # include<iostream>
2 # include<bits/stdc++.h>
3 using namespace std;
4 # define int long long
5 # define endl "\n"
6 const int N = 2e5 + 10;
7 vector<int> g[N];
8 int s[N];
9 int c[N];
10 map<pair<int, int>, int> mp;
11 int f[N][2];
12 int d[N];
13 int dfs2(int u, int F) {
14 d[u] = g[u].size();
15 if(d[u] == 0) return F*s[u];
16 if (mp.count({u, F})) return mp[ {u, F}];//当前状态是否被搜索过
17 int f0 = F / d[u];//平分状态的路径数
18 int re = F % d[u];
19 int sum = F * s[u];
20 int f1 = (F + d[u] - 1) / d[u];//多获取状态的路径数
21 priority_queue<int> q;
22 for (auto v : g[u]) {
23 f[v][0] = dfs2(v, f0);
24 if (f0 == f1) f[v][1] = f[v][0];
25 else f[v][1] = dfs2(v, f1);
26 sum += f[v][0];
27 q.push(f[v][1] - f[v][0]);//优先队列保存的是多出来的路径所能产生的最大贡献
28 }
29 while (re--) {
30 sum += q.top();
31 q.pop();
32 }
33 return mp[ {u, F}] = sum;
34
35 }
36 void solve() {
37 int n, k;
38 cin >> n >> k;
39 mp.clear();
40 for (int i = 1; i <= n; ++i) {
41 g[i].clear();
42 f[i][1] = f[i][0] = 0;
43 }
44 for (int i = 2; i <= n; ++i) {
45 int x;
46 cin >> x;
47 g[x].push_back(i);
48 }
49 for (int i = 1; i <= n; ++i) cin >> s[i];
50 cout << dfs2(1, k) << endl;
51
52 }
53 int tt;
54 signed main() {
55 ios::sync_with_stdio(false);
56 cin.tie(0);
57 cout.tie(0);
58 tt = 1;
59
61 cin >> tt;
62 while (tt--)solve();
63
64
65 return 0;
66 }

最新文章

  1. Java面向对象基础知识汇总
  2. PHPCMS如何开启手机站点
  3. 《DSP using MATLAB》为什么要z变换?
  4. nginx服务器中的安全配置
  5. POJ3264Balanced Lineup 线段树练手
  6. html5移动端制作知识点总结
  7. Emmet:HTML/CSS代码快速编写神器(转)
  8. DAO是什么技术
  9. 转:有关Java泛型的类型擦除(type erasing)
  10. 写一个Windows上的守护进程(8)获取进程路径
  11. DevExpress 学习使用之 PrintSystem
  12. css样式自动换行/强制换行
  13. R语言︱异常值检验、离群点分析、异常值处理
  14. TCP三次握手详解及释放连接过程
  15. Java 并发集合的实现原理
  16. WordPress版微信小程序2.2.0版发布
  17. Object.create() vs new SomeFunction() in javascript
  18. 疫苗:JAVA HASHMAP的死循环
  19. 并发之synchronized关键字的应用
  20. Ubuntu下RabbitMQ安装

热门文章

  1. 使用Python的selenium库制作脚本,支持后台运行
  2. 在DispatcherServlet.class中的,获取方法值中获取到的都是arg值
  3. 性能调优——小小的log大大的坑
  4. Homework5
  5. git cherry-pick 总结
  6. android 逆向 smali手写helloworld
  7. 03 最小CMake项目
  8. Python-Django模板
  9. SpringBoot实战派读书笔记---响应式编程
  10. 详解ROMA Connect API 流控实现技术