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. C#--用户密码处理------混淆密码加密

    近期刚好做新框架的用户数据安全这块 密码的保护措施:混淆加密--------------------------------拙见----------贴上代码--请指教 1:生成混淆数据,---存入数据 ...

  2. 0 or 1(hdu2608)数学题

    0 or 1 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  3. Mybatis标签bind用法

    Mybatis使用bind元素进行模糊查询,不用在乎数据库是mysql还是oracle从而提高可移植性 使用bind元素传递多个参数 public List<Student> findSt ...

  4. 伯克利开源 Confluo,吞吐量是 Kafka 的 4 到 10 倍

    近日伯克利 RISE Lab 开源了一个多数据流实时分布式分析系统 Confluo,它既是一个网络监控和诊断框架,也可以作为时序数据库和发布订阅消息系统. 源码地址:https://github.co ...

  5. Function,Object.creat();

    一.Object.creat()使用方法 Object.creat(对象): 功能:实现继承,创建一个原型继承自参数的对象. 什么是原型式继承:就是利用修改原型链的结构(增加一个节点中的成员,删除一个 ...

  6. input不可编辑且颜色不变

    <input name="ly_qq" type="text" tabindex="2" onMouseOver="this ...

  7. 洛谷P2881 [USACO07MAR]排名的牛Ranking the Cows(bitset Floyd)

    题意 题目链接 Sol 显然如果题目什么都不说的话需要\(\frac{n * (n - 1)}{2}\)个相对关系 然后求一下传递闭包减掉就行了 #include<bits/stdc++.h&g ...

  8. 【读书笔记】iOS-iOS6 Passbook应用开发

    Passbook 是iOS6的新功能,只能在iPhone和iPod touch设备中使用,它可以帮助管理商家发放的电子会员卡,积分卡,优惠券等. 一,Passbook 与 Pass. Passbook ...

  9. idea配置热部署

    第一步:添加依赖使用spring-boot-devtools提供的开发者工具spring-boot项目中引入如下依赖 <dependency><groupId>org.spri ...

  10. vertical-align 详解

    vertical-align用来设置垂直对齐方式,所有垂直对齐的元素都会影响行高 值: baseline | sub | super | top | text-top | middle | botto ...