• bzoj2427


    题解:

    如果是一个环,那么就是每个点都要

    否则就是一个数

    然后dp

    tarjan强连通+树形dp

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1005;
    int n,m,cnt,last[N],x,last2[N],inq[N],scc,ind,top,v[N];
    int w[N],sv[N],sw[N],dfn[N],low[N],belong[N],q[N],f[N][N],in[N];
    struct edge
    {
        int to,next;
    }e[N],ed[N];
    void jb(int u,int v)
    {
        e[++cnt].to=v;
        e[cnt].next=last[u];
        last[u]=cnt;
    }
    void jb2(int u,int v)
    {
        in[v]=1;
        ed[++cnt].to=v;
        ed[cnt].next=last2[u];
        last2[u]=cnt;
    }
    void tarjan(int x)
    {
        int now=0;
        low[x]=dfn[x]=++ind;
        q[++top]=x;inq[x]=1;
        for (int i=last[x];i;i=e[i].next)
         if (!dfn[e[i].to])
          {
            tarjan(e[i].to);
            low[x]=min(low[x],low[e[i].to]);
          }
         else if(inq[e[i].to])
          low[x]=min(low[x],dfn[e[i].to]);
        if (low[x]==dfn[x])
         {
            scc++;
            while (now!=x)
             {
                now=q[top--];inq[now]=0;
                belong[now]=scc;
                sv[scc]+=v[now];
                sw[scc]+=w[now];
             }
         }
    }
    void rebuild()
    {
        cnt=0;
        for (int x=1;x<=n;x++)
         for (int i=last[x];i;i=e[i].next)
          if (belong[e[i].to]!=belong[x])
           jb2(belong[x],belong[e[i].to]);
    }
    void dp(int x)
    {
        for (int i=last2[x];i;i=ed[i].next)
         {
            dp(ed[i].to);
            for (int j=m-sw[x];j>=0;j--)
             for (int k=0;k<=j;k++)
              f[x][j]=max(f[x][j],f[x][k]+f[ed[i].to][j-k]);    
         }
        for (int j=m;j>=0;j--)
         if (j>=sw[x])f[x][j]=f[x][j-sw[x]]+sv[x];
         else f[x][j]=0;
    }
    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)jb(x,i);
         }  
        for (int i=1;i<=n;i++)
         if (!dfn[i])tarjan(i);
        rebuild();
        for (int i=1;i<=scc;i++)
         if (!in[i])jb2(scc+1,i);
        dp(scc+1);
        printf("%d
    ",f[scc+1][m]);
        return 0;
    }
  • 相关阅读:
    Refined Architecture阶段
    大三下学期第三周总结
    信息领域热词分析的-质量属性战术-可用性战术
    Docker ------ Dockerfile初探
    Docker ------ Swarm 初探
    Docker ------ Compose 初探
    正则表达式
    CRNN模型
    Docker容器 ---- pycharm远程连接
    python tgz包安装
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7746155.html
Copyright © 2020-2023  润新知