zoukankan      html  css  js  c++  java
  • Lis(bzoj 3532)

    Description

     给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci。请删除若
    干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案。
        如果有多种方案,请输出将删去项的附加属性排序之后,字典序最小的一种。
      

    Input

      输入包含多组数据。
        输入的第一行包含整数T,表示数据组数。接下来4*T行描述每组数据。
        每组数据的第一行包含一个整数N,表示A的项数,接下来三行,每行N个整数A1..An,B1.,Bn,C1..Cn,满足1 < =Ai,Bi,Ci < =10^9,且Ci两两不同。

    Output

        对每组数据,输出两行。第一行包含两个整数S,M,依次表示删去项的代价和与数量;接下来一行M个整数,表示删去项在4中的的位置,按升序输出。

    Sample Input

    1
    6
    3 4 4 2 2 3
    2 1 1 1 1 2
    6 5 4 3 2 1

    Sample Output

    4 3
    2 3 6
    解释:删去(A2,43,A6),(A1,A6),(A2,43,44,A5)等都是合法的方案,但
    {A2,43,A6)对应的C值的字典序最小。

    HINT

    1 < =N < =700     T < =5

    /*
        如果没有字典序最小的要求,建图跑最小割。
        建图方法:
        S向i连一条容量为inf的边;
        i'向T连一条容量为inf的边;
        i向i'连一条容量为b[i]的边;
        如果a[i]<a[j]&&f[i]+1=f[j],i'向j连一条容量为inf的边。
        
        现在有字典序最小的要求,那么有字典序从小到大枚举删哪条边,删一条边<u,v>的方法是:
        退流,u向S跑一遍最大流,,T向v跑一遍最大流,然后这条边流量清零就行了。 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define N 710
    #define inf 1000000000
    using namespace std;
    int a[N],b[N],f[N],head[N],dis[N],n,cnt,ans[N];
    struct Node{int num,id;}c[N];
    struct node{int v,f,pre;}e[N*N];
    queue<int> q;
    bool cmp(const Node&x,const Node&y){return x.num<y.num;}
    void add(int u,int v,int f){
        e[++cnt].v=v;e[cnt].f=f;e[cnt].pre=head[u];head[u]=cnt;
        e[++cnt].v=u;e[cnt].f=0;e[cnt].pre=head[v];head[v]=cnt;
    }
    bool bfs(int S,int T){
        memset(dis,-1,sizeof(dis));
        q.push(S);dis[S]=0;
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].pre)
                if(e[i].f&&dis[e[i].v]==-1){
                    dis[e[i].v]=dis[u]+1;
                    q.push(e[i].v);
                }
        }
        return dis[T]!=-1;
    }
    int dfs(int x,int f,int T){
        if(x==T||f==0) return f;
        int rest=f;
        for(int i=head[x];i;i=e[i].pre)
            if(e[i].f&&dis[e[i].v]==dis[x]+1){
                int v=dfs(e[i].v,min(rest,e[i].f),T);
                if(!v) dis[e[i].v]=-1;
                e[i].f-=v;
                e[i^1].f+=v;
                rest-=v;
            }
        if(f==rest) dis[x]=0;
        return f-rest;
    }
    int dinic(int S,int T){
        int ans=0;
        while(bfs(S,T)) ans+=dfs(S,inf,T);
        return ans;
    }
    int DP(){
        int maxf=0;
        for(int i=1;i<=n;i++){
            int maxn=0;
            for(int j=0;j<i;j++)
                if(a[j]<a[i]) maxn=max(maxn,f[j]);
            f[i]=maxn+1;
            maxf=max(maxf,f[i]);
        }
        return maxf;
    }
    void build(int S,int T){
        int maxf=DP();
        for(int i=1;i<=n;i++) add(i,i+n,b[i]);
        for(int i=1;i<=n;i++){
            if(f[i]==1) add(S,i,inf);
            else if(f[i]==maxf) add(i+n,T,inf);
            for(int j=i+1;j<=n;j++)
                if(a[i]<a[j]&&f[i]+1==f[j])
                    add(i+n,j,inf);
        }
    }
    int main(){
        int Q;scanf("%d",&Q);
        while(Q--){
            memset(head,0,sizeof(head));
            cnt=1;
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            for(int i=1;i<=n;i++) scanf("%d",&b[i]);
            for(int i=1;i<=n;i++) scanf("%d",&c[i].num),c[i].id=i;
            int S=0,T=n*2+1;
            build(S,T);
            int maxflow=dinic(S,T);
            sort(c+1,c+n+1,cmp);
            int tot=0;
            for(int i=1;i<=n;i++){
                int u=c[i].id,v=u+n;
                if(bfs(u,v)) continue;
                ans[++tot]=u;
                dinic(u,S);dinic(T,v);
                e[u*2].f=e[u*2+1].f=0;
            }
            sort(ans+1,ans+tot+1);
            printf("%d %d
    ",maxflow,tot);
            for(int i=1;i<=tot;i++)
                printf("%d%c",ans[i],i==tot?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    继承映射
    一对多,多对一,自关联的配置
    Spring 配置自动扫描spring bean配置
    Dao 处理
    2019暑假集训 括号匹配
    2019暑假集训 BLO
    2019暑假集训 Intervals
    2019暑假集训 平板涂色
    2019暑假集训 走廊泼水节
    0002-五层小山
  • 原文地址:https://www.cnblogs.com/harden/p/6720315.html
Copyright © 2011-2022 走看看