zoukankan      html  css  js  c++  java
  • bzoj2427: [HAOI2010]软件安装

    一开始的想法:top判一下环,然后直接D

    然后其实整个环一起取是合法的

    所以无脑缩点

    然而森林转二叉树+treedp真的慢到爆炸,10s跑不出一个点

    Rose:我从来都是直接多叉D  (%%%%%%

    然后就%了一发fyc,然后学会了。(或许某天我又会回来补)

    垃圾森林转二叉

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,next;
    }a[510];int len,last[110];
    void eins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    
    int z,dfn[110],low[110];
    int top,sta[110];bool V[110];
    int cnt,belong[110];
    void strong_unicom(int x)
    {
        dfn[x]=low[x]=++z;
        sta[++top]=x;V[x]=true;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]==0)
            {
                strong_unicom(y);
                low[x]=min(low[x],low[y]);
            }
            else
            {
                if(V[y]==true)
                    low[x]=min(low[x],dfn[y]);
            }
        }
        if(low[x]==dfn[x])
        {
            int i;cnt++;
            do
            {
                i=sta[top];top--;
                V[i]=false;
                belong[i]=cnt;
            }while(i!=x);
        }
    }
    
    //---------strong unicom-------
    
    struct tree
    {
        int lc,rc;
    }tr[110];int rit[510];
    void ins(int x,int y)
    {
        if(rit[x]!=0)
        {
            int t=rit[x];
            rit[x]=y;
            x=t;
            
            tr[x].rc=y;
        }
        else tr[x].lc=y, rit[x]=y;
    }
    
    int n;
    int w[510],v[510],d[510];
    int nw[110],nv[110],nd[110];
    void composition()
    {
        nw[0]=nv[0]=0;
        for(int i=1;i<=n;i++)
        {
            nw[belong[i]]+=w[i];
            nv[belong[i]]+=v[i];
            if(belong[d[i]]!=belong[i])nd[belong[i]]=belong[d[i]];
        }
        memset(rit,0,sizeof(rit));
        for(int i=1;i<=cnt;i++)
            if(nd[i]==0)
                ins(cnt+1,i);
            else 
                ins(nd[i],i);
                
    }
    
    //-------composition----------
    
    int f[110][510];
    void dfs(int x,int m)
    {
        if(f[x][m]!=0)return ;
        if(tr[x].lc==0&&tr[x].rc==0)return ;
        
        for(int i=0;i<=m;i++)//分给兄弟 
        {
            int sum=0;
            int d=m-i;
            if(d>=nw[x])
            {
                sum+=nv[x];
                if(tr[x].lc!=0)
                {
                    dfs(tr[x].lc,d-nw[x]);
                    sum+=f[tr[x].lc][d-nw[x]];
                }
            }
            if(tr[x].rc!=0)
            {
                dfs(tr[x].rc,i);
                sum+=f[tr[x].rc][i];
            }
            f[x][m]=max(f[x][m],sum);
        }
    }
    
    //---treeDP--------
    
    int main()
    {
        int m;
        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]);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&d[i]);
            eins(d[i],i);
        }
        
        z=top=cnt=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(belong,0,sizeof(belong));
        memset(V,false,sizeof(V));
        for(int i=1;i<=n;i++)
            if(dfn[i]==0)
                strong_unicom(i);
        composition();
        
        memset(f,0,sizeof(f));
        dfs(cnt+1,m);
        printf("%d
    ",f[cnt+1][m]);
        return 0;
    }

    AC:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,next;
    }e[510];int elen,elast[110];
    void eins(int x,int y)
    {
        elen++;
        e[elen].x=x;e[elen].y=y;
        e[elen].next=elast[x];elast[x]=elen;
    }
    
    int z,dfn[110],low[110];
    int top,sta[110];bool V[110];
    int cnt,belong[110];
    void strong_unicom(int x)
    {
        dfn[x]=low[x]=++z;
        sta[++top]=x;V[x]=true;
        for(int k=elast[x];k;k=e[k].next)
        {
            int y=e[k].y;
            if(dfn[y]==0)
            {
                strong_unicom(y);
                low[x]=min(low[x],low[y]);
            }
            else
            {
                if(V[y]==true)
                    low[x]=min(low[x],dfn[y]);
            }
        }
        if(low[x]==dfn[x])
        {
            int i;cnt++;
            do
            {
                i=sta[top];top--;
                V[i]=false;
                belong[i]=cnt;
            }while(i!=x);
        }
    }
    
    //---------strong unicom-------
    
    node a[510];int len,last[510];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    
    int n;
    int w[510],v[510],d[510];
    int nw[110],nv[110],nd[110];
    void composition()
    {
        nw[0]=nv[0]=0;
        for(int i=1;i<=n;i++)
        {
            nw[belong[i]]+=w[i];
            nv[belong[i]]+=v[i];
            if(belong[d[i]]!=belong[i])nd[belong[i]]=belong[d[i]];
        }
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=cnt;i++)
            if(nd[i]==0)
                nd[i]=cnt+1, ins(nd[i],i);
            else 
                ins(nd[i],i);
                
    }
    
    //-------composition----------
    
    int m,g[110],f[110][510];
    void dfs(int x)
    {
        g[x]=g[nd[x]]+nw[x];
        for(int i=m;i>=g[x];i--)
            f[x][i]=max(f[x][i],f[nd[x]][i-nw[x]]+nv[x]);
        for(int k=last[x];k;k=a[k].next)dfs(a[k].y);
        int fa=nd[x];
        for(int fa=nd[x];fa;fa=nd[fa])
            for(int i=0;i<=m;i++)f[fa][i]=max(f[fa][i],f[x][i]);
    }
    
    //---treeDP--------
    
    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]);
        elen=0;memset(elast,0,sizeof(elast));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&d[i]);
            eins(d[i],i);
        }
        
        z=top=cnt=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(belong,0,sizeof(belong));
        memset(V,false,sizeof(V));
        for(int i=1;i<=n;i++)
            if(dfn[i]==0)
                strong_unicom(i);
        composition();
        
        memset(f,0,sizeof(f));
        dfs(cnt+1);
        printf("%d
    ",f[cnt+1][m]);
        return 0;
    }
  • 相关阅读:
    使用三星720n液晶显示器的体会
    昨天终于买显示器了
    2005525早上
    抵制日货的结果zt
    读写配置文件类
    递归 访问树节点
    IE条件注释
    闭包 页面渐变
    模块 替换HTML 字符实体(双引号、左右尖括号)
    闭包 查找节点序号
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8530554.html
Copyright © 2011-2022 走看看