题目链接

看到代价和价值这两个关键词,肯定是首先要想到背包的。

但是图中并没有说这是棵树,所以先要\(Tarjan\)缩点,然后就是选课了,跑一遍树形背包就好了。

注意:缩点后应该是一个森林,应该用一个虚点连接所有根。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. const int MAXN = 110;
  6. const int MAXM = 1010;
  7. struct Edge{
  8. int next, from, to;
  9. }e[MAXM << 1];
  10. int head[MAXN], num;
  11. inline void Add(int from, int to){
  12. e[++num] = (Edge){ head[from], from, to };
  13. head[from] = num;
  14. }
  15. int vis[MAXN], stack[MAXN], dfn[MAXN], low[MAXN], sum[MAXN], w[MAXN], v[MAXN], W[MAXN], V[MAXN], fa[MAXN], belong[MAXN];
  16. int s[MAXN], t[MAXN], f[MAXN][MAXM], in[MAXN];
  17. int n, m, top, ID, cnt, ans;
  18. void Tarjan(int u){
  19. dfn[u] = low[u] = ++ID;
  20. vis[u] = 1; stack[++top] = u;
  21. for(int i = head[u]; i; i = e[i].next)
  22. if(!dfn[e[i].to]){
  23. Tarjan(e[i].to);
  24. low[u] = min(low[u], low[e[i].to]);
  25. }
  26. else if(vis[e[i].to]) low[u] = min(low[u], dfn[e[i].to]);
  27. if(dfn[u] == low[u]){
  28. ++cnt;
  29. do{
  30. W[cnt] += w[stack[top]];
  31. V[cnt] += v[stack[top]];
  32. vis[stack[top]] = 0;
  33. belong[stack[top]] = cnt;
  34. }while(stack[top--] != u);
  35. }
  36. }
  37. void dp(int u){
  38. f[u][W[u]] = V[u];
  39. for(int i = head[u]; i; i = e[i].next){
  40. dp(e[i].to);
  41. for(int j = m; j >= W[u]; --j)
  42. for(int k = W[e[i].to]; j - k >= W[u]; ++k)
  43. f[u][j] = max(f[u][j], f[e[i].to][k] + f[u][j - k]);
  44. }
  45. }
  46. int main(){
  47. scanf("%d%d", &n, &m);
  48. for(int i = 1; i <= n; ++i)
  49. scanf("%d", &w[i]);
  50. for(int i = 1; i <= n; ++i)
  51. scanf("%d", &v[i]);
  52. for(int i = 1; i <= n; ++i){
  53. scanf("%d", &fa[i]);
  54. Add(fa[i], i);
  55. }
  56. if(head[0]) Tarjan(0);
  57. for(int i = 1; i <= n; ++i)
  58. if(!dfn[i])
  59. Tarjan(i);
  60. num = 0;
  61. memset(head, 0, sizeof head);
  62. for(int i = 1; i <= m; ++i)
  63. if(belong[i] != belong[fa[i]])
  64. Add(belong[fa[i]], belong[i]), ++in[belong[i]];
  65. for(int i = 1; i <= cnt; ++i)
  66. if(!in[i]){
  67. Add(cnt + 1, i);
  68. }
  69. dp(cnt + 1);
  70. for(int i = 1; i <= m; ++i)
  71. ans = max(ans, f[cnt + 1][i]);
  72. printf("%d\n", ans);
  73. return 0;
  74. }

【洛谷 P2515】 [HAOI2010]软件安装 (缩点+树形背包)的更多相关文章

  1. 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)

    题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...

  2. 洛谷 P2515 [HAOI2010]软件安装 解题报告

    P2515 [HAOI2010]软件安装 题目描述 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到 ...

  3. 洛谷—— P2515 [HAOI2010]软件安装

    题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...

  4. 洛谷 P2515 [HAOI2010]软件安装

    题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...

  5. 洛谷——P2515 [HAOI2010]软件安装

    https://www.luogu.org/problem/show?pid=2515#sub 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中 ...

  6. 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)

    传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...

  7. bzoj2427 [HAOI2010]软件安装——缩点+树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2427 今天的考试题...好不容易一次写对了树形DP,却没发现有环的情况... 发现自己 ta ...

  8. luogu P2515 [HAOI2010]软件安装 |Tarjan+树上背包

    题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为MM计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但 ...

  9. [bzoj2427]P2515 [HAOI2010]软件安装(树上背包)

    tarjan+树上背包 题目描述 现在我们的手头有 \(N\) 个软件,对于一个软件 \(i\),它要占用 \(W_i\) 的磁盘空间,它的价值为 \(V_i\).我们希望从中选择一些软件安装到一台磁 ...

  10. [bzoj2427][HAOI2010]软件安装——强连通分量+树形DP

    题目大意 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...

随机推荐

  1. scidb

    貌似是给科学家用的数据库,暂不研究

  2. go 语言模拟百度登录

    1.参考网上Python的例子自己写了一个go语言的.这个仅供学习技术参考,为了方便有部分参数直接phantomjs执行js获取,代码基本都有注释,测试打印没有删除,还请见谅! 2.本文参考http: ...

  3. 6.爬虫 requests库讲解 总结

    requests库的总结: 用ProcessOn根据前面的几节内容做了个思维导图:

  4. 九度OJ--1164(C++)

    #include <iostream>#include <vector> using namespace std; int main() { int n; // n为矩阵阶数 ...

  5. Spark实战练习03--Pair RDD

    一.场景 现有某网站的网站日志,内容为用户对网站的请求,包含user ID.IP address.datetime……等等 另有一份文件中包含用户的账户详细信息数据,包含User ID.creatio ...

  6. ACM训练大纲

    1. 算法总结及推荐题目 1.1 C++ STL • STL容器: set, map, vector, priority_queue, queue, stack, deque, bitset• STL ...

  7. 详细解析@Resource和@Autowired的区别 , 以及@Qualifier的作用

    (41)  (0) 首先 . @Resource是javax.annotation 包中的注解类 , 是jdk中封装的 . @AutoWired是spring的中注解,依赖于spring上下文. 相同 ...

  8. 如何在MyEclipse下查看JDK源代码

    在MyEclipse中查看JDK类库的源代码~ 设置: 1.点 "window"-> "Preferences" -> "Java&quo ...

  9. [剑指Offer] 43.左旋转字符串

    题目描述 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”abc ...

  10. android中常见的命名及其特点详解

    Paseal命名法 Paseal命名法特点:String MyName-DelphiInt MyAge每个单词首字母大写 Camel命名法 Camel(驼峰的意思)命名法特点:String myNam ...