直接退流复杂度好优越啊

LOJ #2196


题意

一段数列,每个点有点权$ A_i$,删除代价$ B_i$,附加属性$ C_i$

求最小代价使得$ LIS$长度发生变化,且输出一种$ C_i$字典序最小的方案


$ Solution$

首先可以求出以每个点结尾的$ LIS$长度数组$ f_i$

按照套路建图

$ i向i+n$连边权为删除代价的边

若$ f_i$=1则$ S向i$连边权为$ INF$的边

若$ f_i$=$ans$则 $i+n向T$连边权为$ INF$的边

然后最小割即是答案

跑一遍最大流即可

考虑输出方案

我们按$ C_i$从小到大枚举每条边,判断这条边是否是割边

若是则选它并删除这条边的贡献

删除之后不需要重新流一遍

只需要从$ i$向$ S$流一遍再从$T$向$ i+n$流一遍去掉贡献

最后再把边的流量上限改成$ 0$即可

复杂度可能是$ O(n^3)$的?


$ my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define INF 1000000000
#define M 1000010
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int i,j,k,m,n,x,y,z,cnt,sum,S,T;
int A[],B[],f[];
int F[M],N[M],L[M],a[M],c[M],dis[M],cur[M],Gap[M];
void add(int x,int y,int z){
a[++k]=y;c[k]=z;
if(!F[x])F[x]=k;
else N[L[x]]=k;
L[x]=k;
}
int q[M],h,t;
bool BFS(int S,int T){
h=;q[t=]=S;
memset(dis,,*sum+);memcpy(cur,F,*sum+);
dis[S]=;
while(h<t){
int x=q[++h];
for(rt i=F[x];i;i=N[i])if(c[i]&&dis[a[i]]>sum){
q[++t]=a[i];
dis[a[i]]=dis[x]+;
if(a[i]==T)return ;
}
}
return ;
}
int dfs(int x,int y,int flow){
int used=;
if(x==y)return flow;
for(rt i=cur[x];i;i=cur[x]=N[i])if(c[i]&&dis[x]+==dis[a[i]]){
int v=dfs(a[i],y,min(flow-used,c[i]));
if(!v)continue;
c[i]-=v;c[i^]+=v;used+=v;
if(used>=flow)return used;
}
if(!--Gap[dis[x]])dis[S]=sum+;
++Gap[++dis[S]];
return used;
}
int dinic(int S,int T){
int ans=,now;Gap[]=sum;
while(BFS(S,T)){
memset(dis,,sizeof(dis));
while(now=dfs(S,T,INF))ans+=now;
}
return ans;
}
struct node{
int x,val;
bool operator <(const node s)const{
return val<s.val;
}
}C[];
int ans[],tot;
int main(){
for(rt QAQ=read();QAQ;QAQ--){
for(rt i=;i<=sum;i++)F[i]=;
for(rt i=;i<=k;i++)L[i]=N[i]=;
n=read();k=;
for(rt i=;i<=n;i++)A[i]=read();
for(rt i=;i<=n;i++)B[i]=read();
for(rt i=;i<=n;i++)C[i].val=read(),C[i].x=i;
for(rt i=;i<=n;i++)f[i]=;
for(rt i=;i<=n;i++)
for(rt j=;j<i;j++)if(A[i]>A[j])f[i]=max(f[i],f[j]+); int maxf=*max_element(f+,f+n+);
for(rt i=;i<=n;i++)add(i,i+n,B[i]),add(i+n,i,);
sort(C+,C+n+);S=n*+,sum=T=n*+; for(rt i=;i<=n;i++)
for(rt j=i+;j<=n;j++)if(f[j]==f[i]+)add(i+n,j,INF),add(j,i+n,);
for(rt i=;i<=n;i++)if(f[i]==)add(S,i,INF),add(i,S,);
for(rt i=;i<=n;i++)if(f[i]==maxf)add(i+n,T,INF),add(T,i+n,);
write(dinic(S,T));putchar(' '); tot=;
for(rt i=;i<=n;i++)if(!BFS(C[i].x,C[i].x+n)){
c[C[i].x<<]=c[C[i].x<<|]=;
dinic(T,C[i].x+n);dinic(C[i].x,S);
ans[++tot]=C[i].x;
}
sort(ans+,ans+tot+);writeln(tot);
for(rt i=;i<=tot;i++)write(ans[i]),putchar(' ');putchar('\n');
}
return ;
}

LOJ #2196「SDOI2014」LIS的更多相关文章

  1. @loj - 2196@「SDOI2014」Lis

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定序列 A,序列中的每一项 Ai 有删除代价 Bi 和附加属性 ...

  2. 「SDOI2014」Lis 解题报告

    「SDOI2014」Lis 题目描述 给定序列 \(A\),序列中的每一项 \(A_i\) 有删除代价 \(B_i\) 和附加属性 \(C_i\). 请删除若干项,使得 \(A\) 的最长上升子序列长 ...

  3. 「SDOI2014」向量集 解题报告

    「SDOI2014」向量集 维护一个向量集合,在线支持以下操作: A x y :加入向量 \((x, y)\): Q x y l r:询问第 \(L\) 个到第 \(R\) 个加入的向量与向量 \(( ...

  4. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  5. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  6. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  7. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  8. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  9. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

随机推荐

  1. SNP在世界地图上的频率分布

    简单介绍两个网页工具,第一个是GGV,其界面如下: 第二个工具是HGDP,个人感觉画出来有点丑..都是同一所大学开发出来的:界面如下:

  2. Android Eclipse 安装教程 hosts替换

    http://www.cnblogs.com/Potato-lover/p/5582542.html 第一步,也是最为关键的一步——修改hosts文件 为什么说是最关键的一步呢?因为接下来的操作,我们 ...

  3. prototype 与 proto的关系是什么:

    __proto__是什么? 我们在这里简单地说下.每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto_ ...

  4. POJ 2240 Arbitrage (Bellman Ford判正环)

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:27167   Accepted: 11440 Descri ...

  5. Microsoft Windows CVE-2017-8464 LNK 远程代码执行漏洞(复现)

    2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞,完全控 ...

  6. day14-jdbc案例(简单的curd&分页)

    回顾: mvc jsp的设计模式1: jsp+javabean jsp的设计模式2: jsp+javabean+servlet jsp:展示数据 javabean:封装数据 封装对数据的访问 serv ...

  7. Python继承扩展内置类

    继承最有趣的应用是给内置类添加功能,在之前的Contact类中,我们将联系人添加到所有联系人的列表里,如果想通过名字来搜索,那么就可以在Contact类添加一个方法用于搜索,但是这种方法实际上属于列表 ...

  8. Java基础构造方法和this关键字整理

    构造方法 8.1构造方法介绍 构造方法的格式: 修饰符 构造方法名(参数列表) { } l  构造方法的体现: n  构造方法没有返回值类型.也不需要写返回值.因为它是为构建对象的,对象创建完,方法就 ...

  9. Linux学习笔记:【002】ARM指令流水线

    指令的处理 在CPU中,对于指令的处理一般分为: 1.取指令阶段 取指令(Instruction Fetch,IF)阶段是将一条指令从主存中取到指令寄存器的过程. 程序计数器PC中的数值,用来指示当前 ...

  10. ACM-ICPC 2018 焦作赛区网络预赛 B Mathematical Curse(DP)

    https://nanti.jisuanke.com/t/31711 题意 m个符号必须按顺序全用,n个房间需顺序选择,有个初始值,问最后得到的值最大是多少. 分析 如果要求出最大解,维护最大值是不能 ...