zoukankan      html  css  js  c++  java
  • P3308 [SDOI2014]LIS(最小割+退流)

    传送门

    (f[i])为以(i)结尾的最长上升子序列。可以考虑建这样一张图,对于所有的(i<j,f[j]=f[i+1])连边((i,j))(f[i]=1)的话连边((S,i))(f[i]=max(f[j]))的话连边((j,T)),然后就是删去若干个点使(S,T)不连通并且代价最小,那么拆点最小割就行了

    然后是字典序的问题。我们把所有的点按(c)排个序然后看看这个点也就是新图中的这条边是否可以在最小割里。只要判断一下残量网络中是否存在(u)(u+n)的路径就是了

    然后删去这条边之后要重新算最大流,如果直接计算会T,这样的话我们可以退流,就是从(T)(u+n)跑一次最大流再从(u)(S)跑一次最大流就可以消除这条边的影响

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define inf 0x3f3f3f3f
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1e4+5,M=1e6+5;
    struct eg{int v,nx,w;}e[M];int head[N],tot=1;
    inline void add(R int u,R int v,R int w){
    	e[++tot]={v,head[u],w},head[u]=tot;
    	e[++tot]={u,head[v],0},head[v]=tot;
    }
    struct node{
    	int c,id;
    	inline bool operator <(const node &b)const{return c<b.c;}
    }c[N];
    int dep[N],q[N],a[N],b[N],f[N],st[N];
    int n,m,mx,S,T,h,t,top,flow;
    bool bfs(int S,int T){
    	fp(i,0,(n<<1|1))dep[i]=-1;q[h=t=1]=S,dep[S]=0;
    	while(h<=t){
    		int u=q[h++];go(u)if(dep[v]<0&&e[i].w){
    			dep[v]=dep[u]+1,q[++t]=v;
    			if(v==T)return true;
    		}
    	}return false;
    }
    int dfs(int u,int T,int lim){
    	if(u==T||!lim)return lim;int flow=0,f;
    	go(u)if(dep[v]==dep[u]+1&&(f=dfs(v,T,min(lim,e[i].w)))){
    		flow+=f,lim-=f,e[i].w-=f,e[i^1].w+=f;
    		if(!lim)break;
    	}if(!flow)dep[u]=-1;return flow;
    }
    inline int dinic(int S,int T){int flow=0;while(bfs(S,T))flow+=dfs(S,T,inf);return flow;}
    inline void cl(){memset(head,0,sizeof(head)),mx=0,tot=1;}
    void solve(){
    	cl(),n=read();
    	fp(i,1,n)a[i]=read();
    	fp(i,1,n)b[i]=read();
    	fp(i,1,n)c[i].c=read(),c[i].id=i;
    	fp(i,1,n){
    		f[i]=1;
    		fp(j,1,i-1)if(a[j]<a[i])cmax(f[i],f[j]+1);
    		cmax(mx,f[i]);
    	}S=0,T=n<<1|1,top=0;
    	fp(i,1,n)add(i,i+n,b[i]);
    	fp(i,1,n)if(f[i]==1)add(S,i,inf);
    	fp(i,1,n)if(f[i]==mx)add(i+n,T,inf);
    	fp(i,1,n)fp(j,1,i-1)if(a[j]<a[i]&&f[i]==f[j]+1)add(j+n,i,inf);
    	flow=dinic(S,T);sort(c+1,c+1+n);
    	fp(i,1,n){
    		int u=c[i].id;if(bfs(u,u+n))continue;
    		dinic(T,u+n),dinic(u,S),st[++top]=u;
    	}sort(st+1,st+1+top);printf("%d %d
    ",flow,top);
    	fp(i,1,top)printf("%d%c",st[i]," 
    "[i==top]);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	int cas=read();
    	while(cas--)solve();
    	return 0;
    }
    
  • 相关阅读:
    关于JSON可能出现的错误,待更/todo
    mongoose的安装与使用(书签记录) 2017
    HTTP的学习记录3--HTTPS和HTTP
    HTTP的学习记录(二)头部
    HTTP(一)概述
    LeetCode 455. Assign Cookies
    LeetCode 453. Minimum Moves to Equal Array Elements
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 447. Number of Boomerangs
    LeetCode 416. Partition Equal Subset Sum
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10140161.html
Copyright © 2011-2022 走看看