【HAOI2010】【强连通分量】【树形动态规划】软件安装
2013-04-10 09:02
441 查看
这道题是一道水题。。。
由于软件的依赖关系可能是一个环,所以先将原图缩点。
将缩点后的树转化为二叉树后f[i][j]表示以i为跟的子树分配j的空间得到的最大价值,l[i],r[i]表示i的左儿子和右儿子
则f[i][j] = max(f[r[i]][j],f[l[i]][k] + f[r[i]][j - k - w[i]] + v[i])
使用记忆化实现。
代码:
由于软件的依赖关系可能是一个环,所以先将原图缩点。
将缩点后的树转化为二叉树后f[i][j]表示以i为跟的子树分配j的空间得到的最大价值,l[i],r[i]表示i的左儿子和右儿子
则f[i][j] = max(f[r[i]][j],f[l[i]][k] + f[r[i]][j - k - w[i]] + v[i])
使用记忆化实现。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100 + 10; const int maxm = 500 + 10; struct tree { int l,r; tree(){l = r = -1;} }Tree[maxn]; struct pnode { int pos; pnode *next; pnode(){} pnode(int pos,pnode *next):pos(pos),next(next){} }*first[maxn],__[maxn],*tot = __; int w[maxn],v[maxn],nw[maxn],nv[maxn]; int dfn[maxn],low[maxn],stack[maxn]; int belong[maxn],dig[maxn]; int f[maxn][maxm]; bool instack[maxn],map[maxn][maxn]; int step = 0,stop = 0,cnt = 0; int n,m; void init() { freopen("bzoj2427.in","r",stdin); freopen("bzoj2427.out","w",stdout); } void readdata() { 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++) { int tmp; scanf("%d",&tmp); first[tmp] = new(tot++)pnode(i,first[tmp]); } } void tarjan(int u) { dfn[u] = low[u] = ++step; stack[stop++] = u; instack[u] = true; for(pnode *p = first[u];p != NULL;p = p -> next) { int v = p -> pos; if(!dfn[v]) { tarjan(v); if(low[v] < low[u])low[u] = low[v]; } else if(instack[v] && dfn[v] < low[u])low[u] = dfn[v]; } if(dfn[u] == low[u]) { cnt++; int tmp; do { tmp = stack[--stop]; instack[tmp] = false; belong[tmp] = cnt; nw[cnt] += w[tmp]; nv[cnt] += v[tmp]; }while(tmp != u); } } void build_map() { for(int u = 1;u <= n;u++) { for(pnode *p = first[u];p != NULL;p = p -> next) { int v = p -> pos; if(belong[u] != belong[v]) { ++dig[belong[v]]; map[belong[u]][belong[v]] = true; } } } } void build_tree(int k) { for(int i = 1;i <= cnt;i++) { if(map[k][i]) { if(Tree[k].l == -1)Tree[k].l = i; else { int t = Tree[k].l; while(Tree[t].r != -1)t = Tree[t].r; Tree[t].r = i; } } } if(Tree[k].l != -1)build_tree(Tree[k].l); if(Tree[k].r != -1)build_tree(Tree[k].r); } int dfs(int d,int k) { if(d == -1)return 0; if(f[d][k] != -1)return f[d][k]; f[d][k] = dfs(Tree[d].r,k); for(int i = 0;i <= k - nw[d];i++) { f[d][k] = max(f[d][k],dfs(Tree[d].l,i) + dfs(Tree[d].r,k - i - nw[d]) + nv[d]); } return f[d][k]; } void solve() { memset(f,-1,sizeof(f)); step = stop = 0; for(int i = 1;i <= n;i++) { if(!dfn[i])tarjan(i); } build_map(); for(int i = 1;i <= cnt;i++) { if(!dig[i])map[0][i] = true; } build_tree(0); printf("%d\n",dfs(0,m)); } int main() { init(); readdata(); solve(); return 0; }
相关文章推荐
- luogu P2515 [HAOI2010]软件安装
- 【BZOJ2427】【HAOI2010】软件安装 tarjan+树形背包DP
- bzoj2427 [HAOI2010]软件安装
- BZOJ 2427: [HAOI2010]软件安装|树形动规|tarjan
- bzoj2427: [HAOI2010]软件安装
- BZOJ 2427: [HAOI2010]软件安装
- [HAOI2010]软件安装
- [Bzoj 2427] [HAOI2010] 软件安装
- bzoj2427 [HAOI2010]软件安装
- bzoj 2427: [HAOI2010]软件安装【tarjan+树形dp】
- [bzoj2427][HAOI2010]软件安装 Tarjan+树形DP
- 2427: [HAOI2010]软件安装
- 洛谷 P2515 [HAOI2010]软件安装
- [HAOI2010][BZOJ2427] 软件安装|tarjan|树型dp
- 洛谷 P2515 [HAOI2010]软件安装
- 【bzoj2427】[HAOI2010]软件安装
- 【bzoj2427】【HAOI2010】【软件安装】【缩点+dp】
- BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包
- BZOJ 2427 [HAOI2010]软件安装 | 这道树形背包裸题严谨地证明了我的菜
- bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)