软件安装「HAOI2010」
作者:互联网
题意
有\(n\)个软件,每个软件都可能有一个依赖软件(换言之,不安装依赖软件就不能安装该软件)。每个软件都有自己的容量和价值,已知总容量,求最大价值。
思路
tarjan+树上背包裸题。
代码
#include <bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T>inline void read (T &x) {
x=0;T f=1;char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T>inline void write (T x) {
if (x<0) putchar('-'),x*=-1;
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
namespace Project {
const int N=505;
int n,m,tim,top,num;
int cnt,cnt2;
int head[N],head2[N];
struct node {
int to,next;
} edge[N<<1],edge2[N<<1];
int dfn[N],low[N],sta[N],instack[N],belong[N];
int cost[N],W[N],V[N],G[N][N],d[N],f[N][N],val[N];
inline void add (int a,int b) {
edge[++cnt].to=b,edge[cnt].next=head[a],head[a]=cnt;
}
inline void add2 (int a,int b) {
edge2[++cnt2].to=b,edge2[cnt2].next=head2[a],head2[a]=cnt2;
}
void tarjan (int now) {
dfn[now]=low[now]=++tim;
sta[++top]=now,instack[now]=1;
for (register int i=head[now]; i; i=edge[i].next) {
int to=edge[i].to;
if (!dfn[to]) {
tarjan(to),low[now]=min(low[now],low[to]);
} else if (instack[to]) low[now]=min(low[now],dfn[to]);
}
if (dfn[now]==low[now]) {
int v;belong[now]=++num,instack[now]=0;
while (v=sta[top--],v!=now) {
belong[v]=num,instack[v]=0;
}
}
}
void dp (int now) {
for (register int i=cost[now]; i<=m; ++i) f[now][i]=val[now];
for (register int e=head2[now]; e; e=edge2[e].next) {
int to=edge2[e].to;
dp(to);
for (register int i=m-cost[now]; i>=0; --i) {
for (register int j=0; j<=i; ++j) {
f[now][i+cost[now]]=max(f[now][i+cost[now]],f[now][i+cost[now]-j]+f[to][j]);
}
}
}
}
inline void MAIN () {
read(n),read(m);
for (register int i=1; i<=n; ++i) read(W[i]);
for (register int i=1; i<=n; ++i) read(V[i]);
for (register int i=1; i<=n; ++i) {
int x;read(x);
if (x) add(x,i);
}
for (register int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i);
for (register int i=1; i<=n; ++i) {
cost[belong[i]]+=W[i],val[belong[i]]+=V[i];
for (register int e=head[i]; e; e=edge[e].next) {
int to=edge[e].to;
if (belong[i]!=belong[to]) G[belong[i]][belong[to]]=1,d[belong[to]]++;
}
}
for (register int i=1; i<=num; ++i) {
for (register int j=1; j<=num; ++j) {
if (G[i][j]) add2(i,j);
}
}
for (register int i=1; i<=num; ++i) {
if (!d[i]) add2(num+1,i);
}
dp(num+1);
printf("%d\n",f[num+1][m]);
}
}
int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
Project::MAIN();
}
标签:10,int,namespace,StandardIO,HAOI2010,软件,安装,getchar 来源: https://www.cnblogs.com/ilverene/p/11402225.html