• 图论.DP


    见题:

    看一眼,就知道是个依赖性背包,于是乎就草草的打了树上DP,一交发现才20,仔细检查也没错呀,忍不住点了题解,只喵一眼看到了强联通缩点等的字样,又重新审了一遍题,发现这句话理解有偏差:软件i只有在安装了软件j(包括软件j的直接或间接依赖)。题目并未说i依赖j时,j就不能依赖i了,所以就形成了环了。

    代码:

    #include<bits/stdc++.h>
    #define max(a,b) (((a)>(b))?(a):(b))
    #define min(a,b) (((a)<(b))?(a):(b))
    using namespace std;
    const int MAXN=510,maxn=110;
    vector<int>son[maxn];
    int tot,low[maxn],dfn[maxn],link[maxn],stackn[maxn],vis[maxn],top,o;
    int n,w[maxn],v[maxn],m,c,ans[maxn],ww[maxn],vv[maxn],ru[maxn],f[maxn][MAXN]; 
    struct bian
    {
        int y,next;
    };
    bian a[100000];
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-') ff=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*ff;
    }
    inline void put(int x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) put(x/10);
        putchar(x%10+'0');
    }
    inline void add(int x,int y)
    {
        a[++tot].y=y;
        a[tot].next=link[x];
        link[x]=tot;
    }
    inline void tarjan(int x)
    {
        dfn[x]=low[x]= ++o;
        vis[stackn[++top]=x]=1;
        for(int i=link[x];i;i=a[i].next)
        {
            int y=a[i].y;
            if(!dfn[y])
            {
                tarjan(y);
                low[x]=min(low[x],low[y]);
            }
            else if(vis[y]) low[x]=min(dfn[y],low[x]);
        }
        if(dfn[x]==low[x])
        {
            int k;c++;
            do{
                vis[k=stackn[top--]]=0;
                ans[k]=c;
            }while(k!=x);
        }
    }
    inline void dfs(int x)
    {
        for(int i=ww[x];i<=m;i++)f[x][i]=vv[x];
        for(int i=0;i<son[x].size();i++)
        {
            int y=son[x][i];
            dfs(y);
            for(int t=m;t>=ww[x];t--)                       
            {
                for(int k=0;k<=t-ww[x];k++) f[x][t]=max(f[x][t],f[x][t-k]+f[y][k]);
            }
        }
    }
    int main()
    {
        freopen("1.in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=n;i++) w[i]=read();
        for(int i=1;i<=n;i++) v[i]=read();
        for(int i=1;i<=n;i++)
        {
            int x=read();
            if(x) add(x,i);
        }
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=n;i++) ww[ans[i]]+=w[i],vv[ans[i]]+=v[i];
        for(int i=1;i<=n;i++)
        {
            for(int j=link[i];j;j=a[j].next)
            {
                if(ans[i]==ans[a[j].y]) continue;
                son[ans[i]].push_back(ans[a[j].y]);ru[ans[a[j].y]]++;
            }
        }
        for(int i=1;i<=c;i++) if(!ru[i]) son[0].push_back(i);
        dfs(0);
        put(f[0][m]);
        return 0;
    }

    以后看题还需仔细了...

  • 相关阅读:
    C#中调用DTS
    经典问题:向setTimeout传递函数参数
    C#.NET 中的类型转换
    SQL语句导入导出大全 (转载)
    js脚本defer的作用
    [转]使用 Java API 处理 WebSphere MQ 大消息
    WideCharToMultiByte 宽字节转换为多字节
    [原].NET数据库开发中请注意区域时间格式
    输出页眉和页脚的简单HTTP模块实践
    浅析ASP.NET HTTP Module
  • 原文地址:https://www.cnblogs.com/gcfer/p/10607065.html
Copyright © 2020-2023  润新知