zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    SpringMVC-乱码问题
    SpringMVC-数据提交
    SpringMVC-结果跳转方式
    SpringMVC-Controller&RestFul
    SpringMVC-基础
    Spring-声明式事务
    Spring-整合MyBatis
    Spring-AOP
    android 入门-工序
    android 入门-android Studio 解决方案
  • 原文地址:https://www.cnblogs.com/akoasm/p/9419407.html
Copyright © 2011-2022 走看看