[BZOJ2427][HAOI2010]软件安装-tarjan缩点-树上dp
<题面>
这个题真伤人
之前Tarjan和树规都没学好,吃了不少亏,仔仔细细的搞了一天,收获颇丰
先来一个Tarjan的链接:$\mathbb{O}$
题目的数据比较友好:
$dp$不对:$\leq10$
$dp$对了Tarjan不对:$40$
都对了:$100$
接下来就是思路
首先观察题目。
$n$个点$n$条边,也许有环。
所以先以$0$为根节点(虚根,可以想象成”系统“,所有软件的依赖,无价值无内存),这样有一个好处,不用建边时特判,直接建就好了(无依赖是$0$)
额,你要问我怎么建,从被依赖的向依赖的指一个有向边
被依赖的$\Longrightarrow$依赖的,这样建好的图便于转移
建图结束,下面是个重头戏:缩点
这个题缩点极为简单,你会发现,环里的点已经互相依赖,不可能依赖其他的程序(除了虚根,我们暂不考虑)
这是我们就可以把它们打包安装。
首先Tarjan找出这个环,打个标记(我用的用新节点下标)
这样,我们把所有边扫一遍,凡是从环中的点出发的边起点都拽到新节点上,顺便把价值也统过去(别记重了)
最后把新节点连到虚根上。
还是很棒的吧?
然后是$dp$,就是很普通的树上背包。
$f_{i,j}$表示第$i$号节点使用$j$空间时的最大价值
写式子为敬:
$f_{i,j} = \max \limits_{w \leq j , s \in son_i} \{ f_{i,j-w}+f_{s,w} \}$
要从大往小$dp$,防止重复更新(01背包)
#include <iostream>
#include <cstring>
#include <cstdio>
#define N 111
#define M 555
using namespace std; struct STAR{
int f,t,next;
}rs[N*N];int fl[*N],cnt=;
void add(int f,int t){
rs[cnt].f=f;
rs[cnt].t=t;
rs[cnt].next=fl[f];
fl[f]=cnt;
cnt++;
}
int pom,rom;
int val[*N],cost[*N];
struct mystack{
int st[*N],tp;
mystack(){
tp=;
memset(st,,sizeof st);
}
int top(){
return st[tp-];
}
void pop(){
tp--;
}
void push(int k){
st[tp]=k;
tp++;
}
bool empty(){
if(tp==)return true;
return false;
}
}sk;
void prerun(){
memset(fl,-,sizeof fl);
}
int dfn[*N],low[*N],dep=,bl[*N];
bool is_in[*N],is_v[*N],cut[*N];
void tarjan(int k){//cout<<" J "<<k<<endl;
dep++;
dfn[k]=low[k]=dep;
int t;
sk.push(k);
is_in[k]=;
for(int i=fl[k];i!=-;i=rs[i].next){
t=rs[i].t;
if(!dfn[t]){
tarjan(t);
low[k]=min(low[k],low[t]);
}
else{
if(is_in[t]){
low[k]=min(low[k],low[t]);
}
}
}
if(low[k]==dfn[k]){
if(sk.top()==k){
sk.pop();
is_in[k]=;
return;
}
int p=;
pom++;
do{
p=sk.top();
is_in[p]=;
bl[p]=pom;
sk.pop();
}while(p!=k);
}
}
int dp[*N][M];
void dfs(int k){
is_v[k]=;
dp[k][]=;
for(int i=fl[k];i!=-;i=rs[i].next){
int t=rs[i].t;
if(!is_v[t]){
dfs(t);
for(int w=rom;w>=;w--){
for(int m=;m<=rom;m++){
if(w-m>=)
dp[k][w]=max(dp[k][w],dp[k][w-m]+dp[t][m]);
}
}
}
}
for(int i=rom;i>=;i--)
if(i-cost[k]>=)
dp[k][i]=dp[k][i-cost[k]]+val[k];
else
dp[k][i]=;
}
int ans=;
int main(){
int a,beg;
prerun();
scanf("%d%d",&pom,&rom);beg=pom;
for(int i=;i<=pom;i++)
scanf("%d",&cost[i]);
for(int i=;i<=pom;i++)
scanf("%d",&val[i]);
for(int i=;i<=pom;i++){
scanf("%d",&a);
add(a,i);
}
for(int i=;i<=beg;i++){
if(!dfn[i])tarjan(i);
}
for(int i=;i<cnt;i++){
int fo=rs[i].f,to=rs[i].t;
if(bl[fo]!=){//cout<<"Cut"<<rs[i].f<<endl;
if(cut[fo]==){
val[bl[fo]]+=val[fo];
cost[bl[fo]]+=cost[fo];
cut[fo]=;
}
add(bl[fo],to); }
}
for(int i=;i<=beg;i++){
if(bl[i]!=){
is_v[i]=;
fl[i]=-;
}
}
for(int i=beg+;i<=pom;i++){
add(,i);
}
dfs();
for(int i=;i<=rom;i++){
ans=max(ans,dp[][i]);
}
printf("%d\n",ans);
return ;
}
Code
[BZOJ2427][HAOI2010]软件安装-tarjan缩点-树上dp的更多相关文章
- bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp
[HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2029 Solved: 811[Submit][Status][Dis ...
- [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)
点此看题面 大致题意: 有\(N\)个软件,每个软件有至多一个依赖以及一个所占空间大小\(W_i\),只有当一个软件的直接依赖和所有的间接依赖都安装了,它才能正常工作并造成\(V_i\)的价值.求在容 ...
- BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包
分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...
- [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)
如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...
- BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP
终于是道中文题了.... 当时考试的时候就考的这道题.... 果断GG. 思路: 因为有可能存在依赖环,所以呢 先要tarjan一遍 来缩点. 随后就进行一遍树形DP就好了.. x表示当前的节点.j表 ...
- 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包
[BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...
- 【BZOJ-2427】软件安装 Tarjan + 树形01背包
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 960 Solved: 380[Submit][Status ...
随机推荐
- spring:ApplicationContext的三个实现类
* ApplicationContest的三个常用实现类* ClassPathXmlApplicationContext:它可以加载类路径的配置文件,要求配置文件必须在类路径下,如果不在则加载不了* ...
- Luogu P1131 [ZJOI2007]时态同步(dfs)
P1131 [ZJOI2007]时态同步 题意 题目描述 小\(Q\)在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字\(1,2,3,\dots\).进行 ...
- 跟我一起使用socket.io创建聊天应用
安装express插件 新建index.js var app = require('express')(); var http = require('http').Server(app); app.g ...
- html--双飞翼布局
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Error:【SLF4J: Class path contains multiple SLF4J bindings.】
ylbtech-Error:[SLF4J: Class path contains multiple SLF4J bindings.] 1.返回顶部 1. SLF4J: Class path cont ...
- centos7 yum 安装tomcat7
查看yum中tomcat信息 yum info tomcat 安装 yum install tomcat 安装管理界面 yum install tomcat-webapps tomcat-admin- ...
- ireport 无法打开问题
打开时闪退 ,是因为jdk版本过高的原因:https://blog.csdn.net/aust_glj/article/details/52291240 相关软件下载地址: JasperReports ...
- 11_数据降维PCA
1.sklearn降维API:sklearn. decomposition 2.PCA是什么:主成分分析 本质:PCA是一种分析.简化数据集的技术. 目的:是数据维数压缩,尽可能降低原数据的维数(复杂 ...
- Django之模板语言(四) ------>Tags
案例1:单层for循环 # Django 模板语言测试代码 def template_test(request): name_list=["张三","李四",& ...
- 懒散惯了,该收收心了,两天了,封装了一个R0下注册表类
写得乱七八糟. 看着自己写的代码,感觉都不像自己了. 我写的代码,风格这么差了么?思路这么乱了么? 我写代码这么累么? 不像以前的我了... 这段时间,太懒散了... 该继续努 ...