软件安装:树上分组DP/tarjan缩点/(也许基环树?)
提炼:tarjan环缩成点,建0虚根,跑树形DP,最难的是看出可能有n个点n条边然后缩点,n个点n条边可能不只有一个环
n个点n条边->基环树:
基环树,也是环套树,简单地讲就是树上在加一条边。
既然成环就必定要么全选要么全不选,直接缩成一个点即可。
我的错误:
1.第二次建图时跑的第一次的邻接表
2.在读入时就建立了虚根0,但tarjan缩完后将环变成了孤点,建虚根毫无作用
结论:要在有实际意义的前提上对算法作出改进!不能有啥是啥!
Code
#include<cstdio>
using namespace std;
const int N=;
const int V=;
int n,m,rt,num_bian,num_ibian,num_huan,num_tarjan,num_que,
pw[N],pv[N],w[N],v[N],fm[N],to[N],head[N],nxt[N],ito[N],ihead[N],inxt[N],dfn[N],low[N],bel[N],que[N],in_que[N],dp[N][V],ru[N];
void add(int x,int y){
to[++num_bian]=y,fm[num_bian]=x,nxt[num_bian]=head[x],head[x]=num_bian;
}
void iadd(int x,int y){
ito[++num_ibian]=y,inxt[num_ibian]=ihead[x],ihead[x]=num_ibian,ru[y]++;
}
int min(int x,int y){return x>y?y:x;}
int max(int x,int y){return x>y?x:y;}
void tarjan(int x){
dfn[x]=low[x]=++num_tarjan;
que[++num_que]=x;in_que[x]=;
for(int i=head[x],y;i;i=nxt[i])
if(!dfn[y=to[i]])tarjan(y),low[x]=min(low[x],low[y]);
else if(in_que[y])low[x]=min(low[x],dfn[y]);
if(dfn[x]==low[x]){
++num_huan;
int y;
do{
y=que[num_que--];
in_que[y]=;
bel[y]=num_huan;
}while(y!=x);
}
}
void dfs(int x){
for(int i=ihead[x],y;i;i=inxt[i]){
dfs(y=ito[i]);
for(int j=m;j>=;--j)for(int k=j;k;--k)
dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[y][k]);
//printf("dp[%d][%d]=%d\n",x,j,dp[x][j]);
}
if(v[x]!=)for(int i=m;i;--i)
if(i>=v[x])dp[x][i]=dp[x][i-v[x]]+w[x];
else dp[x][i]=;
}
void debug(){
for(int i=;i<=n;++i)printf("%d ",bel[i]);puts("");
for(int i=num_huan;i;--i)printf(":%d %d ",w[i],v[i]);puts("");
printf("%d\n",rt);
}
int main(){
//freopen("text.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)scanf("%d",&pv[i]);for(int i=;i<=n;++i)scanf("%d",&pw[i]);for(int i=,x;i<=n;++i){scanf("%d",&x);if(x)add(x,i);}
for(int i=;i<=n;++i)if(!dfn[i])tarjan(i);
for(int i=;i<=num_bian;++i)if(bel[fm[i]]!=bel[to[i]])iadd(bel[fm[i]],bel[to[i]]);
for(int i=;i<=n;++i)w[bel[i]]+=pw[i],v[bel[i]]+=pv[i];
for(int i=;i<=num_huan;++i)if(!ru[i])iadd(,i);
dfs();
printf("%d\n",dp[][m]);
//debug();
return ;
}
我还贴心的准备了对拍(Linux)代码(其实是我拍了2h呜呜呜)
#include<bits/stdc++.h>
using namespace std;
int main(){
for(int i=;i<=;++i){
system("./1");
system("./2");
system("./rand");
if(system("diff 1.out 2.out")){
puts("Wrong Answer");return ;
}
else puts("Accepted");
}
}
pai.cpp
rand 代码
#include<bits/stdc++.h>
using namespace std;
const int N=;
int main(){
freopen("text.in","w",stdout);
srand((unsigned)time());
int n=rand()%N+,m=rand()%N+;
printf("%d %d\n",n,m);
for(int i=;i<=n;++i){
int v=rand()%n+;
printf("%d ",v);
}puts("");
for(int i=;i<=n;++i){
int w=rand()%n+;
printf("%d ",w);
}puts("");
for(int i=,li;i<=n;++i){
do
li=rand()%n;
while(li==i);
printf("%d ",li);
}puts("");
}
rand.cpp
注:读入text.in,正解1.cpp,输出1.out,你的错解是2.cpp,输出2.out
还不快谢谢我!
软件安装:树上分组DP/tarjan缩点/(也许基环树?)的更多相关文章
- BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP
BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP 题意: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁 ...
- 【BZOJ2427】[HAOI2010]软件安装(动态规划,Tarjan)
[BZOJ2427][HAOI2010]软件安装(动态规划,Tarjan) 题面 BZOJ 洛谷 题解 看到这类题目就应该要意识到依赖关系显然是可以成环的. 注意到这样一个性质,依赖关系最多只有一个, ...
- [BZOJ2427]:[HAOI2010]软件安装(塔尖+DP)
题目传送门 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用${W}_{i}$的磁盘空间,它的价值为${V}_{i}$.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件 ...
- 【Luogu】P2515软件安装(树形DP)
题目链接 这么水的题我一遍没A,而且前两次提交都只有十分.气死我了.本来我的博客拒收水题来着. Tarjan缩点之后跑树形DP即可. #include<cstdio> #include&l ...
- HDU4612+Tarjan缩点+BFS求树的直径
tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...
- hdu2242(树形dp+tarjan+缩点)
hdu2242 http://acm.hdu.edu.cn/showproblem.php?pid=2242 给定n,m表示n个点,m条边 每个点有个权值 问我们删除两某条边(割边)后将图分为两个部分 ...
- [IOI2008/BZOJ1791 岛屿](处理基环树的小技巧&基于bfs树形DP)
IOI2008/BZOJ1791 岛屿 题目大意是在一个基环树森林里求每一棵基环树的直径①的和. 其实就是树的直径的基环树升级版.我们先把环找出来,然后从环上的每一个节点x出发,并且不经过环上其他节点 ...
- bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp
[HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2029 Solved: 811[Submit][Status][Dis ...
- 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)
传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...
随机推荐
- 文件分发服务器 AWS CloudFront(CDN)使用入门-以S3为例 Lebal:Research
引言 在互联网上随意右击一张图片,都可以发现复制图片地址这个选项,这说明他们都有自己的链接(直链),也就是说我们可以通过一个链接本身来访问图片.代码等文件,而不是打开一个网页再选择复制,这就和下载链接 ...
- Java servlet和JSP的区别和联系
Java servlet技术:在Java代码中嵌入HTML JSP技术:HTML输出时比较便捷,就在HTML中嵌入Java代码 Java servlet技术:擅长编写Java代码 JSP技术:擅长页面 ...
- ListView控件,表格模式下,如何调整行高
参考说明: https://www.codeproject.com/Articles/1401/Changing-Row-Height-in-an-owner-drawn-Control 如果所有项的 ...
- freebsd 隐藏ssh版本号
方案一: vi /etc/ssh/sshd_config VersionAddendum 为空或者no或者别的信息 /etc/rc.d/sshd restart 方案二: https://kram.n ...
- Linux内存:物理内存管理概述
内存中的物理内存管理 概述 一般来说,linux内核一般将处理器的虚拟地址空间划分为2部分.底部比较大的部分用于用户进程,顶部则专用于内核. 在IA-32系统上,地址空间在用户进程和内核之间划分的典型 ...
- c++面向对象 —— 类和对象
类和对象 类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法.类中的数据和方法称为类的成员.函数在一个类中被称为类的成员. 一.类定义 实际上并没有定义任何数据,但它定义了类的名称意味着什么 ...
- USACO1.5 Mother's Milk【搜索】
题目传送门 这道题还记得是我当年学广搜的时候做过. 如今再做,做了一个$dfs$版本的,比较简单,直接搞就可以了. 广搜的话,用结构体保存,然后塞到$queue$里面就可以了. /* ID: Star ...
- 【神经网络与深度学习】【Matlab开发】caffe-windows使能Matlab2015b接口
[神经网络与深度学习][Matlab开发]caffe-windows使能Matlab2015b接口 标签:[神经网络与深度学习] [Matlab开发] 主要是想全部来一次,所以使能了Matlab的接口 ...
- Maven从入门到精通(四)
这一篇我会着重讲解Maven的核心命令及作用,Maven在项目构建各个阶段的作用. 1.maven生命周期模型: 1.1.清洁(clean) 1.2.默认(default) 1.3.站点(site) ...
- [转帖]SUN/Oracle JDK还是OpenJDK?
你安装的是 https://www.cnblogs.com/shoufeng/p/9719995.html 目录 1 如何查看你安装的JDK版本 1.1 要用到的命令行工具 1.2 查看JDK的版本 ...