[HAOI 2010]软件安装
Posted akoasm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HAOI 2010]软件安装相关的知识,希望对你有一定的参考价值。
题意:求个树形依赖背包
思路:对于环用tarjan缩点即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2010;
struct edge{
int to;
int nxt;
}edge[maxn];
int w[maxn];
int v[maxn];
int dfn[maxn];
int low[maxn];
int scc[maxn];
int Scc;
int alist[maxn];
int cnt;
int dfu;
int fa[maxn];
int f[maxn][maxn<<3];
int n,m,x;
stack<int>s;
vector<int>V[maxn];
int num;
inline void add(int u,int v){
edge[cnt].to=v;
edge[cnt].nxt=alist[u];
alist[u]=cnt;
return;
}
inline void tarjan(int x){
s.push(x);
dfn[x]=low[x]=++dfu;
for(int i=alist[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(!dfn[y])
tarjan(y),
dfn[x]=min(dfn[x],dfn[y]);
else if(!scc[y])
dfn[x]=min(dfn[x],low[y]);
}
if(dfn[x]==low[x]){
++num;
while(s.top()!=x)
scc[s.top()]=num,
s.pop();
s.pop();
scc[x]=num;
}
}
inline void dp(int x,int p){
if(v<0) return;
for(int i=0;V[x].size();i++){
int y=V[x][i];
for(int j=0;j<p;j++)
f[y][j]=f[x][j];
dp(y,p-w[y]);
for(int j=w[y];j<=p;j++)
f[x][j]=max(f[x][j],f[y][j-w[y]]+v[y]);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=1;i<=n;i++)
scanf("%d",&v[i]);
for(int i=1;i<=n;i++){
scanf("%d",&x);
if(x) add(x,i),fa[i]=x;
}
num=n;
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++){
w[scc[i]]+=w[i];
v[scc[i]]+=v[i];
if(scc[fa[i]]!=scc[i])
fa[scc[i]]=scc[fa[i]];
}
for(int i=n+1;i<=num;i++)
V[fa[i]].push_back(i);
dp(0,m);
printf("%d",f[0][m]);
return 0;
}
以上是关于[HAOI 2010]软件安装的主要内容,如果未能解决你的问题,请参考以下文章