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. Java基础——JSP(三)

    一. JavaBean 是一种特殊的java类,它遵从一定的设计模式,开发工具和其他组件可以根据这种模式来调用javaBean.它是使用一种符合某些命名方法和设计规范的java类. -- 这个类是可序 ...

  2. 【Java基础】7、Java同步机制之Monitor监视器与syncrhoized实现原理

    一:Monitor Monitor是一个同步工具,相当于操作系统中的互斥量(mutex),即值为1的信号量. 它内置与每一个Object对象中,相当于一个许可证.拿到许可证即可以进行操作,没有拿到则需 ...

  3. Software-Defined Networking A Comprehensive Survey --阅读_day1

    The Internet has led to the creation of a digital society, where (almost) everything is connected an ...

  4. python-观察者模式

    源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 存在这样的一种情况:公司领导再开例会那天临时有事,他让秘书给所有会上员工群发了一 ...

  5. python-享元模式

    源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 如果一个软件系统在运行时所创建的相同或相似对象数量太多,将导致运行代价过高,带来 ...

  6. 【代码笔记】iOS-对数组进行排序

    一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, ...

  7. 【代码笔记】iOS-JSONKit的使用

    一,工程图. 二,代码. #import "RootViewController.h" //为JSONKit添加头文件 #import "JSONKit.h" ...

  8. Asp Url汉字乱码的问题

    1.js <a target="_blank" href="/asp/download.asp?File=' + escape(item.FileName) + ' ...

  9. java发起HTTP请求的共用类

    一定要注意编码,请求时,content-type里的编码,仅仅是流的编码,而结果的编码类型,则是流转化为字符串是需要设定的. 以下是3种使用get/post的方式: import java.io.Bu ...

  10. AutoCompleteTextView 自定义提示样式

    项目中用到AutoCompleteTextView  自动提示功能,如果用自带的ArrayAdapter就一种样式,非常丑,而且每一项提示文字过多的话不会自动换行. 所以自己自定义了一个适配器. 效果 ...