题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2427

今天的考试题...好不容易一次写对了树形DP,却没发现有环的情况...

发现自己 tarjan 都不太熟了,差点没写上那个 vis 数组!

还有点要注意的地方,如果一个环跟外部都不连边,要专门把它连到0点上去;

然后就是普通的树形DP了。

代码如下:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. int n,m,w[],v[],head[],ct,f[][],siz[],ans,cr,col[],hd[],cnt;
  6. int dfn[],low[],tim,sta[],top,vv[],ww[];
  7. bool vis[],in[];
  8. struct N{
  9. int to,next;
  10. N(int t=,int n=):to(t),next(n) {}
  11. }edge[],ed[];
  12. void dp(int x)
  13. {
  14. siz[x]=ww[x]; f[x][ww[x]]=vv[x]; f[x][]=;
  15. // cout<<x<<endl;
  16. // printf("%d head=%d\n",x,head[x]);
  17. for(int j=hd[x],u;j;j=ed[j].next)
  18. {
  19. dp(u=ed[j].to);
  20. siz[x]+=siz[u];
  21. for(int i=min(m,siz[x]);i>=ww[x];i--)
  22. for(int k=min(i-ww[x],siz[u]);k>=;k--)
  23. // {
  24. f[x][i]=max(f[x][i],f[u][k]+f[x][i-k]);
  25. // if(f[x][i]>=0)printf("u=%d i=%d k=%d f[%d][%d]=%d\n",u,i,k,x,i,f[x][i]);
  26. // }
  27. }
  28. // printf("return:%d\n",x);
  29. }
  30. void tarjan(int x)
  31. {
  32. dfn[x]=low[x]=++tim;
  33. sta[++top]=x; vis[x]=;//
  34. for(int i=head[x];i;i=edge[i].next)
  35. {
  36. int u=edge[i].to;
  37. if(!dfn[u])
  38. {
  39. tarjan(u);low[x]=min(low[x],low[u]);
  40. }
  41. else if(vis[u])//
  42. low[x]=min(low[x],dfn[u]);
  43. }
  44. if(low[x]==dfn[x])
  45. {
  46. cr++;
  47. while(sta[top]!=x)
  48. {
  49. col[sta[top]]=cr;
  50. ww[cr]+=w[sta[top]];
  51. vv[cr]+=v[sta[top]];
  52. vis[sta[top]]=; top--;
  53. }
  54. ww[cr]+=w[x]; vv[cr]+=v[x];
  55. col[x]=cr; vis[x]=; top--;
  56. }
  57. }
  58. int main()
  59. {
  60. // freopen("software.in","r",stdin);
  61. // freopen("software.out","w",stdout);
  62. scanf("%d%d",&n,&m);
  63. for(int i=;i<=n;i++)scanf("%d",&w[i]);
  64. for(int i=;i<=n;i++)scanf("%d",&v[i]);
  65. for(int i=,x;i<=n;i++)
  66. {
  67. scanf("%d",&x);
  68. edge[++ct]=N(i,head[x]); head[x]=ct;
  69. }
  70. for(int i=;i<=n;i++)
  71. if(!dfn[i])tarjan(i);
  72. for(int i=;i<=n;i++)//
  73. for(int j=head[i];j;j=edge[j].next)
  74. {
  75. int u=edge[j].to;
  76. if(col[i]==col[u])continue;//
  77. ed[++cnt]=N(col[u],hd[col[i]]); hd[col[i]]=cnt;
  78. in[col[u]]=;
  79. }
  80. memset(f,-,sizeof f);
  81. for(int i=;i<=cr;i++)
  82. if(in[i]==){ed[++cnt]=N(i,hd[]); hd[]=cnt;}//注意这部分!
  83. dp();
  84. for(int i=;i<=m;i++)ans=max(ans,f[][i]);
  85. printf("%d",ans);
  86. return ;
  87. }

bzoj2427 [HAOI2010]软件安装——缩点+树形DP的更多相关文章

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

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

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

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

  3. bzoj 2427: [HAOI2010]软件安装【tarjan+树形dp】

    一眼最大权闭合子图,然后开始构图,画了画之后发现我其实是个智障网络流满足不了m,于是发现正确的打开方式应该是一眼树上dp 然后仔细看了看性质,发现把依赖关系建成图之后是个奇环森林,这个显然不能直接dp ...

  4. [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1987  Solved: 791[Submit][Statu ...

  5. bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1053  Solved: 424[Submit][Statu ...

  6. BZOJ2427:[HAOI2010]软件安装(树形DP,强连通分量)

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

  7. [BZOJ2427]:[HAOI2010]软件安装(塔尖+DP)

    题目传送门 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用${W}_{i}$的磁盘空间,它的价值为${V}_{i}$.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件 ...

  8. 题解【bzoj2427 [HAOI2010]软件安装】

    Description 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到一台磁盘容量为\(M\)计算 ...

  9. bzoj2427: [HAOI2010]软件安装

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

随机推荐

  1. java动态代理实现与原理详细分析(【转载】By--- Gonjan )

    [转载]By---Gonjan  关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式     ...

  2. Microsoft SQL Server 安全与权限

    Microsoft SQL Server 安全与权限 登陆角色 计算机操作系统用户 --创建Windows身份验证用户 USE [master] GO CREATE LOGIN [计算机名称\计算机用 ...

  3. nginx+keepalived+tomcat+memcache实现双VIP高可用及Session会话保持

    Nginx+Keepalived+Tomcat+Memcached 实现双VIP负载均衡及Session会话保持 IP 信息列表: 名称         IP                      ...

  4. SQL删除重复数据(根据多个字段),pandas的nan存入数据库报错

    delete from M_FACTOR_DATA_TEST a where (a.factor_id,a.data_date,a.stock_code) in (select factor_id,d ...

  5. 个人Linux(ubuntu)使用记录——远程访问linux

    说明:记录自己的linux使用过程,并不打算把它当作一个教程,仅仅只是记录下自己使用过程中的一些命令,配置等东西,这样方便自己查阅,也就不用到处去网上搜索了,所以文章毫无章法可言,甚至会记录得很乱. ...

  6. Luogu P3802 小魔女帕琪

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  7. java--删除链表偶数节点

    public class ListNode { int data;//当前节点的值 ListNode next = null;//是指向下一个节点的指针/引用 public ListNode(int ...

  8. Stones HDU 1896

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1896 题目大意: 有n个石头,每个石头有:p  它所在的位置 ,d  它能扔多远 从0 开始,遇到第奇 ...

  9. [luoguP1072] Hankson 的趣味题(数论)

    传送门 由题意得 gcd(x, a0) = a1 ——> gcd(x / a1, a0 / a1) = 1 lcm(x, b0) = b1 ——> x * b0 / gcd(x, b0) ...

  10. hdu 5050 java程序求大数最大公约数

    import java.io.*; import java.math.*; import java.util.*; import java.text.*; public class Main { pu ...