Description

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


按在上升子序列中的位置连成网络,拆点之间限流为\(b\),显然跑一波最小割最长上升子序列长度就会减一

但是字典序最小的割边要怎么找呢QAQ

如果一条正向边满流了而且在残图中这条边的起点到终点不连通那么这条边就可以是割边

当然了啊如果这条边甚至没有满流它怎么可能成为割边,如果去掉这条边还是联通那去掉了也没有什么用同样不可能是割边

然后就把序列按照c排序,把拆出来的\(n\) 条边先连上,然后一个个判断这条边是不割边。

注意判断是割边后要把这条边退流,这样的话和这条边在同一条路径上的边就不会被选重了

这样是可以保证字典序最小的,每一个长度能到达答案的上升序列都包含一个被流掉的点,贪心并不会使后面的边的选择变劣


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define M 150000
using namespace std;

int n,m,k,t,ver[M],edge[M],head[M],nex[M],cnt=1,c[M],T,ans,cur[M],d[M],maxx,fr[M],p[M],l;
queue <int> q;

struct vv
{
    int a,b,c,w,f;
} v[M];

bool cmp(vv a,vv b) {return a.c<b.c;}
void modi(int x,int k){for(int i=x;i<=n;i+=i & -i) c[i]=max(c[i],k);}
int ask(int x){int ans=0; for(int i=x;i>0;i-=i & -i) ans=max(ans,c[i]); return ans;}
void add(int x,int y,int z)
{
    ver[++cnt]=y; nex[cnt]=head[x]; head[x]=cnt; edge[cnt]=z; fr[cnt]=x;
    ver[++cnt]=x; nex[cnt]=head[y]; head[y]=cnt; edge[cnt]=0;
}

bool bfs(int S,int T)
{
    memcpy(cur,head,sizeof(head));
    memset(d,0,sizeof(d));
    while(q.size()) q.pop();
    d[S]=1; q.push(S);
    while(q.size())
    {
        int x=q.front(); q.pop();
        for(int i=head[x];i;i=nex[i])
        if(edge[i] && !d[ver[i]])
        {
            d[ver[i]]=d[x]+1;
            if(ver[i]==T) return 1;
            q.push(ver[i]);
        }
    }
    return 0;
}

int dinic(int x,int flow,int T)
{
    if(x==T || !flow) return flow;
    int re=flow, k;
    for(int& i=cur[x];i && re;i=nex[i])
    if(edge[i] && d[ver[i]]==d[x]+1)
    {
        int k=dinic(ver[i],min(re,edge[i]),T);
        re-=k; edge[i]-=k; edge[i^1]+=k;
        if(!k) d[ver[i]]=0;
    }
    return flow-re;
}

int main()
{
    scanf("%d",&T);
    for(;T;T--)
    {
        memset(head,0,sizeof(head)); memset(nex,0,sizeof(nex));
        cnt=1, ans=maxx=l=0; memset(c,0,sizeof(c));
        scanf("%d",&n); t=2*n+1;
        for(int i=1;i<=n;i++) scanf("%d",&v[i].a);
        for(int i=1;i<=n;i++) scanf("%d",&v[i].b);
        for(int i=1;i<=n;i++) scanf("%d",&v[i].c), v[i].w=i;
        for(int i=1;i<=n;i++)
        {
            v[i].f=ask(v[i].a-1)+1; maxx=max(maxx,v[i].f);
            modi(v[i].a,v[i].f);
        }
        sort(v+1,v+1+n,cmp);
        for(int i=1;i<=n;i++) add(v[i].w,v[i].w+n,v[i].b);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++) if(v[j].w>v[i].w && v[j].f==v[i].f+1 && v[j].a>v[i].a)
                add(v[i].w+n,v[j].w,0x3f3f3f3f);
            if(v[i].f==1) add(0,v[i].w,0x3f3f3f3f);
            if(v[i].f==maxx) add(v[i].w+n,t,0x3f3f3f3f);
        }
        while(bfs(0,t)) while(k=dinic(0,0x3f3f3f3f,t)) ans+=k;
        for(int i=2;i<=n+n+2;i+=2)
        if(!edge[i] && ver[i]==fr[i]+n && fr[i]  &&!bfs(fr[i],ver[i]))
        {
            p[++l]=fr[i];
            bfs(fr[i],0); while(dinic(fr[i],edge[i^1],0));
            bfs(t,ver[i]); while(dinic(t,edge[i^1],ver[i]));
        }
        sort(p+1,p+1+l);
        printf("%d %d\n",ans,l);
        for(int i=1;i<=l;i++)  printf("%d ",p[i]);
        printf("\n");
    }
}

3532: [Sdoi2014]Lis的更多相关文章

  1. 3532: [Sdoi2014]Lis 最小字典序最小割

    3532: [Sdoi2014]Lis Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 865  Solved: 311[Submit][Status] ...

  2. BZOJ 3532: [Sdoi2014]Lis (最大流)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3532 题意:给出三个数列ABC,长度均为n.删除A中的某些数字,使得A的最长上升子 ...

  3. BZOJ.3532.[SDOI2014]LIS(最小割ISAP 退流)

    BZOJ 洛谷 \(LIS\)..经典模型? 令\(f_i\)表示以\(i\)结尾的\(LIS\)长度. 如果\(f_i=1\),连边\((S,i,INF)\):如果\(f_i=\max\limits ...

  4. [BZOJ]3532: [Sdoi2014]Lis

    Time Limit: 10 Sec  Memory Limit: 512 MB Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序 ...

  5. bzoj千题计划141:bzoj3532: [Sdoi2014]Lis

    http://www.lydsy.com/JudgeOnline/problem.php?id=3532 如果没有字典序的限制,那么DP拆点最小割即可 加上字典序的限制: 按c从小到大枚举最小割边集中 ...

  6. BZOJ3532 : [Sdoi2014]Lis

    f[i]表示以i为结尾的LIS长度 对于所有f[i]=1的,由S向i连边 对于所有f[i]=maxf的,由i向T连边 对于j<i,a[j]<a[i],且f[j]+1=f[i]的,j向i连边 ...

  7. 【bzoj3532】 Sdoi2014—Lis

    http://www.lydsy.com/JudgeOnline/problem.php?id=3532 (题目链接) 题意 给出$n$个数的数列,三个值$a[i],b[i],c[i]$.将其中一些数 ...

  8. [SDOI2014]LIS

    这道题还是非常好的 首先第一问可以让我们联想到某网络流二十四题里的一道题,发现建图方式应该和这道题差不多啊 所以首先跑一遍\(dp\),求出\(dp[i]\)表示\(i\)位置结束的\(LIS\)长度 ...

  9. [bzoj3532][Sdoi2014]Lis——拆点最小割+字典序+退流

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

随机推荐

  1. Windows下当地RabbitMQ服务的安装

    Windows下本地RabbitMQ服务的安装 本文参考:刘若泽相关技术文档 当然这些内容页可以通过RabbitMQ官方网站获得. RabbitMQ配置说明手册 一.RaibbitMQ服务器配置 1. ...

  2. Sql动态查询拼接字符串的优化

    Sql动态查询拼接字符串的优化 最原始的 直接写:string sql="select * from TestTables where 1=1";... 这样的代码效率很低的,这样 ...

  3. oracleHelper 操作帮助类

    using System; using System.Configuration; using System.Data; using System.Collections; using Oracle. ...

  4. 当堆遇到STL 代码焕发光芒

    来自度娘的释义,堆的含义大概是这样的: 感性理解: 堆(英语:heap)是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.堆总是满足下列性质: 堆中某个节点的值总是不大于 ...

  5. javaer有福了,基于Web的mysql数据库管理工具TreeSoft发布了。

    基于Web的数据库管理工具TreeSoft数据库管理系统发布快3年了,版本不断更快速迭代开发中,QQ群也积累了300多位粉丝,虽然时不时也掉粉,但总体还是增加中.大家虽然捐赠不多,但是苍蝇再小也是肉啊 ...

  6. Code Signal_练习题_differentSymbolsNaive

    Given a string, find the number of different characters in it. Example For s = "cabca", th ...

  7. SpringBoot简介、特点

    ##SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包.SpringBoot整合了所有的框架,并通过一行简单的main方法启动应用. ##微框 ...

  8. html垂直居中

    参考于http://www.cnblogs.com/yugege/p/5246652.html <!DOCTYPE html> <html lang="en"&g ...

  9. AJAX删除事件与加载数据

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. android开发之braodCast

    广播问题: 遇到了broadcast中sendBroadcast之后,注册registerReceiver的receiver接受不到广播,原因是permisson权限问题. 自定义的permissio ...