zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    MVC,KVO,KVC的简单认识
    Objective-C之集合对象
    Objective-C之词典对象
    Objective-C之数组对象
    Objective-C关键字static
    IOS做天气预报
    同步和异步GET,POST请求
    iOS开发常用的开源库和示例
    KVC KVO KVB
    iOS中的 沙盒文件夹 (数据的写入和读取,归档和反归档)
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7746155.html
Copyright © 2011-2022 走看看