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. MFC函数—CWinApp::LoadStdProfileSettings

    从 InitInstance 成员函数内调用该函数,启用和加载最近使用的(MRU)文件和最后浏览状态的列表.void LoadStdProfileSettings(   UINT nMaxMRU = ...

  2. thinkphp 返回上一页的两种方式

    <div > <a class="details_back" href="{:U('Admin/SinglePageManagement/index') ...

  3. API 与 SDK

    API 和SDK是软件行业的两个缩写词. API (Application Programming Interface)=应用程序编程接口 通过一套套的要求,用来管理应用程序之间的沟通.一个API相当 ...

  4. Java基础——字符编码

    一.ASII 美国(国家)信息交换标准(代)码. 计算机中只有数字,一切都是用数字表示,屏幕上显示的一个一个的字符也不例外. 一个字节可表示的数字为0-255,足以显示键盘上的所有的字符 例如. a ...

  5. Spring、Springmvc整合web的web.xml配置

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  6. JavaOne 2016主旨演讲畅谈Java近期及远期规划

    在 JavaOne 2016 主题演讲开场,来自 Oracle 的 Java 产品管理负责人 Sharat Chander 指出 Java 盛行于个人和工作的日常生活各个领域,无论是大数据.物联网甚至 ...

  7. HDU1083(KB10-C 二分图最大匹配)

    Courses Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  8. 解决stackoverflow打开缓慢的问题

    一.原因: 因为stackoverflow用的是谷歌的api,在国内谷歌是被禁用的,所以才会打开缓慢,并不是stackverflow被墙 二.解决方法: 1.如果你正在使用的是火狐浏览器,那么请按照下 ...

  9. 学习笔记(3)——实验室集群WMS服务配置

    1.启动mgt结点的tomcat服务: [root@mgt zmq]# /home/geohpc/softwares/apache-tomcat-/bin/startup.sh 关闭为 [root@m ...

  10. 004-React-Native--多图选择上传

    参考资料:http://www.jianshu.com/p/488e62ed9656 一:使用react-native-image-crop-picker进行图片选择时,并没有提供多图的机制.当你从相 ...