bzoj2427 [HAOI2010]软件安装——缩点+树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2427
今天的考试题...好不容易一次写对了树形DP,却没发现有环的情况...
发现自己 tarjan 都不太熟了,差点没写上那个 vis 数组!
还有点要注意的地方,如果一个环跟外部都不连边,要专门把它连到0点上去;
然后就是普通的树形DP了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,w[],v[],head[],ct,f[][],siz[],ans,cr,col[],hd[],cnt;
int dfn[],low[],tim,sta[],top,vv[],ww[];
bool vis[],in[];
struct N{
int to,next;
N(int t=,int n=):to(t),next(n) {}
}edge[],ed[];
void dp(int x)
{
siz[x]=ww[x]; f[x][ww[x]]=vv[x]; f[x][]=;
// cout<<x<<endl;
// printf("%d head=%d\n",x,head[x]);
for(int j=hd[x],u;j;j=ed[j].next)
{
dp(u=ed[j].to);
siz[x]+=siz[u];
for(int i=min(m,siz[x]);i>=ww[x];i--)
for(int k=min(i-ww[x],siz[u]);k>=;k--)
// {
f[x][i]=max(f[x][i],f[u][k]+f[x][i-k]);
// 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]);
// }
}
// printf("return:%d\n",x);
}
void tarjan(int x)
{
dfn[x]=low[x]=++tim;
sta[++top]=x; vis[x]=;//
for(int i=head[x];i;i=edge[i].next)
{
int u=edge[i].to;
if(!dfn[u])
{
tarjan(u);low[x]=min(low[x],low[u]);
}
else if(vis[u])//
low[x]=min(low[x],dfn[u]);
}
if(low[x]==dfn[x])
{
cr++;
while(sta[top]!=x)
{
col[sta[top]]=cr;
ww[cr]+=w[sta[top]];
vv[cr]+=v[sta[top]];
vis[sta[top]]=; top--;
}
ww[cr]+=w[x]; vv[cr]+=v[x];
col[x]=cr; vis[x]=; top--;
}
}
int main()
{
// freopen("software.in","r",stdin);
// freopen("software.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&w[i]);
for(int i=;i<=n;i++)scanf("%d",&v[i]);
for(int i=,x;i<=n;i++)
{
scanf("%d",&x);
edge[++ct]=N(i,head[x]); head[x]=ct;
}
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int i=;i<=n;i++)//
for(int j=head[i];j;j=edge[j].next)
{
int u=edge[j].to;
if(col[i]==col[u])continue;//
ed[++cnt]=N(col[u],hd[col[i]]); hd[col[i]]=cnt;
in[col[u]]=;
}
memset(f,-,sizeof f);
for(int i=;i<=cr;i++)
if(in[i]==){ed[++cnt]=N(i,hd[]); hd[]=cnt;}//注意这部分!
dp();
for(int i=;i<=m;i++)ans=max(ans,f[][i]);
printf("%d",ans);
return ;
}
bzoj2427 [HAOI2010]软件安装——缩点+树形DP的更多相关文章
- 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)
题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...
- [bzoj2427][HAOI2010]软件安装——强连通分量+树形DP
题目大意 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- bzoj 2427: [HAOI2010]软件安装【tarjan+树形dp】
一眼最大权闭合子图,然后开始构图,画了画之后发现我其实是个智障网络流满足不了m,于是发现正确的打开方式应该是一眼树上dp 然后仔细看了看性质,发现把依赖关系建成图之后是个奇环森林,这个显然不能直接dp ...
- [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1987 Solved: 791[Submit][Statu ...
- bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1053 Solved: 424[Submit][Statu ...
- BZOJ2427:[HAOI2010]软件安装(树形DP,强连通分量)
Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...
- [BZOJ2427]:[HAOI2010]软件安装(塔尖+DP)
题目传送门 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用${W}_{i}$的磁盘空间,它的价值为${V}_{i}$.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件 ...
- 题解【bzoj2427 [HAOI2010]软件安装】
Description 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到一台磁盘容量为\(M\)计算 ...
- bzoj2427: [HAOI2010]软件安装
Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...
随机推荐
- Python学会之后,一般能拿到多少工资?
Python在约40年前出现以来,已经有数以千计基于这项技术的网站和软件项目,Python因其独有的特点从众多开发语言中脱颖而出,深受世界各地的开发者喜爱. 随着Python的技术的流行,Python ...
- Pycharm中通过扩展工具添加QTDesigner
1.在电脑中找到Designer.exe的安装目录: 2.在pycharm中打开file->Settings->Tools->External Tools进行配置: 配置如下图所示: ...
- Appium 的xpath定位
Appium 的xpath定位 1.如果元素text是唯一的,可以通过text文本定位 //*[@text=’text文本属性’] # 定位text driver.find_element_by_xp ...
- Linux安装redis并且连接内网的redis
1.安装redis步骤 1.首先准备工作 [root@10-100-14-130 ~]# yum install gcc-c++ yum install wget 2.推荐进入到linux路径/ ...
- C++ Primer(第4版)-学习笔记-第4部分:面向对象编程与泛型编程
第15章 面向对象编程OOP(Object-oriented programming) 面向对象编程基于三个基本概念:数据抽象.继承和动态绑定. 在 C++ 中,用类进行 ...
- Java写时复制CopyOnWriteArrayList
Copy-On-Write是一种程序设计的优化方法,多线程在不修改对象时可以共享一个对象地址空间,如果某一个线程要求修改对象时,需要首先将原来对象复制一份,在新复制的对象地址空间上修改对象内容,其他线 ...
- 利用WebUploader进行图片批量上传,在页面显示后选择多张图片压缩至指定路径【java】
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览 ...
- 3. Python中的分支判断、循环
本文利用的是Python 3.x版本,建议学习3.x版本 Python中的分支判断.循环 1. 分支条件判断 1.1 比较操作 以下是数之间常见的比较操作,例如5>3就是数学意义上的比较,5是大 ...
- java--删除链表偶数节点
public class ListNode { int data;//当前节点的值 ListNode next = null;//是指向下一个节点的指针/引用 public ListNode(int ...
- HDU 1081 DP找最大和的矩阵
题目大意: 在一个给定的大矩阵中找一个小型的矩阵,使这个矩阵中的元素和最大 可以先来看下面这个问题: 原来有做过在一个给定的数字序列中找一个最大和子序列,核心代码如下: ]; ]; ; ; int r ...