BZOJ.3532.[SDOI2014]LIS(最小割ISAP 退流)
\(LIS\)。。经典模型?
令\(f_i\)表示以\(i\)结尾的\(LIS\)长度。
如果\(f_i=1\),连边\((S,i,INF)\);如果\(f_i=\max\limits_{j=1}^n\{f_j\}\),连边\((i,T,INF)\);如果\(f_i=f_j+1,\ j<i\),连边\((j,i,INF)\)。
这样使\(LIS\)长度至少减少\(1\),就是删掉图中的一些点,使得\(S,T\)不连通。
拆点,把\(i\)拆成\(X_i,Y_i\),连边\((X_i,Y_i,cost_i)\)。\(j\to i\)的连边就连\(Y_j\to X_i\)。
求最小割就可以得到最小花费了。
对于\(C_i\)字典序最小的方案:
把点按照\(C_i\)从小到大排序,我们要依次判断边\((X_i,Y_i)\)是否可以在最小割上。
边\((u,v)\)在最小割上当且仅当,这条边满流,且不能再增广。
对于后一个条件就判断以\(u\)做源点,\(v\)做汇点,是否存在增广路径就可以了(从\(u\)到\(v\) \(BFS\))。
然后如果选择了边\((u,v)\),那经过\((u,v)\)的路径上的其它边都不能再选。把边\((u,v)\)的流量退回去,就可以使这些边一定不在最小割上了。
退流具体就是,以\(u\)做源点,\(S\)做汇点,流\(cap_{(u,v)}\)的流量;再以\(T\)做源点,\(v\)做汇点,流\(cap_{(u,v)}\)的流量。(\(S,T\)是原图的源汇点)
//16392kb 3816ms
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1407,M=705*703*2,INF=0x3f3f3f3f;
int src,des,rk[N],Enum,H[N],nxt[M],to[M],fr[M],cap[M],lev[N],pre[N],dis[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v,int w)
{
to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
to[++Enum]=u, fr[Enum]=v, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
}
inline bool cmp(int a,int b)
{
return rk[a]<rk[b];
}
bool BFS(int S,int T)
{
static int q[N];
const int lim=des+1;
for(int i=0; i<=des; ++i) lev[i]=lim;
int h=0,t=1; q[0]=T, lev[T]=0;
while(h<t)
{
int x=q[h++];
for(int i=H[x]; i; i=nxt[i])
if(lev[to[i]]==lim && cap[i^1])
lev[to[i]]=lev[x]+1, q[t++]=to[i];
}
return lev[S]<=des;
}
inline int Augment(int S,int T,int flow)
{
for(int i=T; i!=S; i=fr[pre[i]])
flow=std::min(flow,cap[pre[i]]);
for(int i=T; i!=S; i=fr[pre[i]])
cap[pre[i]]-=flow, cap[pre[i]^1]+=flow;
return flow;
}
int ISAP(int S,int T,int flow)
{
static int num[N],cur[N];
if(!BFS(S,T)) return 0;
memset(num,0,des+2<<2);
for(int i=0; i<=des; ++i) ++num[lev[i]],cur[i]=H[i];
int res=0,x=S;
while(lev[S]<=des)
{
if(x==T) x=S, res+=Augment(S,T,flow);
bool can=0;
for(int i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]-1 && cap[i])
{
can=1, cur[x]=i, pre[x=to[i]]=i;
break;
}
if(!can)
{
int mn=des;
for(int i=H[x]; i; i=nxt[i])
if(cap[i]) mn=std::min(mn,lev[to[i]]);
if(!--num[lev[x]]) break;
++num[lev[x]=mn+1], cur[x]=H[x];
if(x!=S) x=fr[pre[x]];
}
}
return res;
}
int main()
{
static int A[N],cost[N],f[N],B[N],e[N],Ans[N];
for(int T=read(); T--; )
{
const int n=read(); src=0, des=n<<1|1;
Enum=1, memset(H,0,des+1<<2);
for(int i=1; i<=n; ++i) A[i]=read();
for(int i=1; i<=n; ++i) cost[i]=read();
for(int i=1; i<=n; ++i) rk[i]=read();
int mx=0;
for(int i=1; i<=n; ++i)
{
int tmp=0;
for(int j=1; j<i; ++j) A[i]>A[j]&&(tmp=std::max(tmp,f[j]));
mx=std::max(mx,f[i]=tmp+1);
}
for(int i=1; i<=n; AE(i,i+n,cost[i]),e[i++]=Enum)
if(f[i]!=1)
{
if(f[i]==mx) AE(i+n,des,INF);
for(int j=1; j<i; ++j) if(f[j]+1==f[i] && A[j]<A[i]) AE(j+n,i,INF);
}
else AE(0,i,INF);
int tot=ISAP(0,des,INF);
printf("%d ",tot);
//Subtask2
for(int i=1; i<=n; ++i) B[i]=i;
std::sort(B+1,B+1+n,cmp); int cnt=0;
for(int i=1,x=B[1],ex=e[x]; i<=n&&tot; x=B[++i],ex=e[x])
if(!cap[ex^1] && !BFS(x,x+n))
tot-=cap[ex], Ans[++cnt]=x, ISAP(x,src,cap[ex]), ISAP(des,x+n,cap[ex]), cap[ex]=cap[ex^1]=0;
std::sort(Ans+1,Ans+1+cnt), printf("%d\n",cnt);
for(int i=1; i<=cnt; ++i) printf("%d%c",Ans[i]," \n"[i==cnt]);
}
return 0;
}
BZOJ.3532.[SDOI2014]LIS(最小割ISAP 退流)的更多相关文章
- 3532: [Sdoi2014]Lis 最小字典序最小割
3532: [Sdoi2014]Lis Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 865 Solved: 311[Submit][Status] ...
- [bzoj3532][Sdoi2014]Lis——拆点最小割+字典序+退流
题目大意 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若 干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案. 如果有多种方案,请输出将删去项的附加属性 ...
- BZOJ 3532: [Sdoi2014]Lis (最大流)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3532 题意:给出三个数列ABC,长度均为n.删除A中的某些数字,使得A的最长上升子 ...
- [BZOJ]3532: [Sdoi2014]Lis
Time Limit: 10 Sec Memory Limit: 512 MB Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序 ...
- BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)
题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...
- 【BZOJ-3532】Lis 最小割 + 退流
3532: [Sdoi2014]Lis Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 704 Solved: 264[Submit][Status] ...
- hdu3739 Anti LIS[最小割]
长度为 n≤1000 的数列 ai,其中最长上升子序列的长度为 s.至少删去多少数使得最长上升子序列的长度小于 s. 其实这题和那个求有多少不重叠LIS是一样答案的. 先放个图. 图丑别说我. 原网络 ...
- ACM/ICPC 之 伞兵-最小割转最大流(POJ3308)
//以行列建点,伞兵位置为单向边-利用对数将乘积转加法 //最小割转最大流 //Time:63Ms Memory:792K #include<iostream> #include<c ...
- 【Luogu】P2057善意的投票(最小割转最大流)
题目链接 也算水题一道吧,不过Round1感性理解一下就xjb建了个图,40 Round2仔细分析了一会,理性建了个图,90 然后分析了半天……改大数组就A了…… 从S到所有值为1的点连一条inf的边 ...
随机推荐
- cf1025c 思维题
/* bwwwbwwbw wwbwwwbwb 不管从哪里断开翻转.翻转后的串再整体翻转一定是2s的子串 */ #include<bits/stdc++.h> using namespace ...
- bzoj 4715
其实我并没有见过原题,只是因为...这被改编成了互测题... 题目中提到了一个序列,这个序列是很重要的,否则这个问题好像是没有合理的时间复杂度解法的 但正因为有了这个序列,这个问题的时间复杂度才让人能 ...
- Loadrunner11.0 录制手机App脚本的方法二
lr11安装一个移动补丁以后,就可以支持抓包文件直接转换为http/html协议的脚本.下面简单说一下过程. 1.工作思路:手机连接可上外网wifi,在手机wifi中设置本机ip的网络地址,然后在本机 ...
- GAN-生成手写数字-Keras
from keras.models import Sequential from keras.layers import Dense from keras.layers import Reshape ...
- K3 WISE 开发插件《SQL语句WHERE查询-范围查询/模糊查询》
0.存储过程开头变量定义 @FBeginDate varchar(10), --单据起始日期 @FEndDate varchar(10), --单据截止日期. @FItemID varchar(50) ...
- hbase启动后HMaster进程自动关闭
1.情况描述如题所示,hbase启动以后,HMaster进程启动了,几秒钟以后自动关闭,但是HRegionServer进程正常运行: 原因是,hdfs的默认端口号是8020,而我core-site.x ...
- checkbox选中相关问题总结
html: <input type="checkbox" name="fruit" id="apple">苹果 <inpu ...
- 【CF809D】Hitchhiking in the Baltic States
题意: 给你n个区间[li,ri],让你选出从中一个子序列,然后在子序列的每个区间里都选择一个tj,满足t1<t2<...<tlent1<t2<...<tlen.最 ...
- python之工作目录和文件引用
1.参考 如何获得Python脚本所在目录的位置 Python 相对导入与绝对导入 还没细看 2.不考虑exe打包 sys.path[0] #顶层运行脚本的绝对目录 os.path.split(os. ...
- Crystal Reports报表使用 [一]
1.Crystal Reports 是什么? Crystal Reports 是一个功能强大.动态和可操作的报表解决方案,它将帮助你通过网络设计.开发.可视化及发布报表,或嵌入到企业应用之中.有了它, ...