<题面>

这个题真伤人

之前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的更多相关文章

  1. bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp

    [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2029  Solved: 811[Submit][Status][Dis ...

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

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

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

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

  4. 【BZOJ2427】[HAOI2010] 软件安装(缩点+树形DP)

    点此看题面 大致题意: 有\(N\)个软件,每个软件有至多一个依赖以及一个所占空间大小\(W_i\),只有当一个软件的直接依赖和所有的间接依赖都安装了,它才能正常工作并造成\(V_i\)的价值.求在容 ...

  5. BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包

    分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...

  6. [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)

    如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...

  7. BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP

    终于是道中文题了.... 当时考试的时候就考的这道题.... 果断GG. 思路: 因为有可能存在依赖环,所以呢 先要tarjan一遍 来缩点. 随后就进行一遍树形DP就好了.. x表示当前的节点.j表 ...

  8. 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包

    [BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...

  9. 【BZOJ-2427】软件安装 Tarjan + 树形01背包

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 960  Solved: 380[Submit][Status ...

随机推荐

  1. spring:ApplicationContext的三个实现类

    * ApplicationContest的三个常用实现类* ClassPathXmlApplicationContext:它可以加载类路径的配置文件,要求配置文件必须在类路径下,如果不在则加载不了* ...

  2. Luogu P1131 [ZJOI2007]时态同步(dfs)

    P1131 [ZJOI2007]时态同步 题意 题目描述 小\(Q\)在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字\(1,2,3,\dots\).进行 ...

  3. 跟我一起使用socket.io创建聊天应用

    安装express插件 新建index.js var app = require('express')(); var http = require('http').Server(app); app.g ...

  4. html--双飞翼布局

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Error:【SLF4J: Class path contains multiple SLF4J bindings.】

    ylbtech-Error:[SLF4J: Class path contains multiple SLF4J bindings.] 1.返回顶部 1. SLF4J: Class path cont ...

  6. centos7 yum 安装tomcat7

    查看yum中tomcat信息 yum info tomcat 安装 yum install tomcat 安装管理界面 yum install tomcat-webapps tomcat-admin- ...

  7. ireport 无法打开问题

    打开时闪退 ,是因为jdk版本过高的原因:https://blog.csdn.net/aust_glj/article/details/52291240 相关软件下载地址: JasperReports ...

  8. 11_数据降维PCA

    1.sklearn降维API:sklearn. decomposition 2.PCA是什么:主成分分析 本质:PCA是一种分析.简化数据集的技术. 目的:是数据维数压缩,尽可能降低原数据的维数(复杂 ...

  9. Django之模板语言(四) ------>Tags

    案例1:单层for循环 # Django 模板语言测试代码 def template_test(request): name_list=["张三","李四",& ...

  10. 懒散惯了,该收收心了,两天了,封装了一个R0下注册表类

    写得乱七八糟.   看着自己写的代码,感觉都不像自己了.   我写的代码,风格这么差了么?思路这么乱了么?   我写代码这么累么?   不像以前的我了...   这段时间,太懒散了...   该继续努 ...