• 【HAOI2010】软件安装


    题面

    题解

    缩点之后一个裸的树型背包

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    using std::min; using std::max;
    
    inline int read()
    {
    	int data = 0, w = 1;
    	char ch = getchar();
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(1010);
    struct edge { int next, to; } e[maxn << 1];
    int n, m, e_num, top, col, cnt, W[maxn], w[maxn], V[maxn], v[maxn], f[maxn][maxn], head[maxn];
    
    inline void add_edge(int from, int to)
    {
    	e[++e_num] = (edge) {head[from], to};
    	head[from] = e_num;
    }
    
    int dfn[maxn], low[maxn], stk[maxn], belong[maxn], d[maxn], ind[maxn];
    void Tarjan(int x)
    {
    	dfn[x] = low[x] = ++cnt;
    	stk[++top] = x;
    	for(RG int i = head[x]; i; i = e[i].next)
    	{
    		int to = e[i].to;
    		if(!dfn[to]) Tarjan(to), low[x] = min(low[x], low[to]);
    		else if(!belong[to]) low[x] = min(low[x], dfn[to]);
    	}
    
    	if(dfn[x] == low[x])
    	{
    		belong[x] = ++col; V[col] = v[x]; W[col] = w[x];
    		while(stk[top] != x) belong[stk[top]] = col, V[col] += v[stk[top]], W[col] += w[stk[top--]];
    		--top;
    	}
    }
    
    void dfs(int x)
    {
    	for(RG int i = W[x]; i <= m; i++) f[x][i] = V[x];
    	for(RG int i = head[x]; i; i = e[i].next)
    	{
    		int to = e[i].to; dfs(to);
    		for(RG int j = m - W[x]; j >= 0; j--)
    			for(RG int k = 0; k <= j; k++)
    				f[x][j + W[x]] = max(f[x][j + W[x]], f[to][k] + f[x][j + W[x] - k]);
    	}
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(RG int i = 1; i <= n; i++) scanf("%d", w + i);
    	for(RG int i = 1; i <= n; i++) scanf("%d", v + i);
    	for(RG int i = 1; i <= n; i++) { scanf("%d", d + i); if(d[i]) add_edge(d[i], i); }
    	for(RG int i = 1; i <= n; i++) if(!dfn[i]) Tarjan(i);
    	memset(head, 0, sizeof(head)); memset(e, 0, sizeof(e)); e_num = 0;
    	for(RG int i = 1; i <= n; i++) if(belong[d[i]] != belong[i]) add_edge(belong[d[i]], belong[i]), ++ind[belong[i]];
    	for(RG int i = 1; i <= col; i++) if(ind[i] == 0) add_edge(0, i);
    	dfs(0); printf("%d
    ", f[0][m]);
    	return 0;
    }
    
  • 相关阅读:
    字符串面试题:将句子的单词序倒置
    字符串面试题:将整型转换为字符串
    QML定时器
    QML按键事件处理
    QML鼠标事件实现变色矩形
    QML动态加载组件
    QML鼠标区域控制
    属性绑定与赋值
    设置虚拟机的本地端口映射
    关于修改banner信息;nginx反向代理apache应用
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10220620.html
Copyright © 2020-2023  润新知